为什么Java不能检查这段代码?

Jul*_*les 0 java generics typechecking

我有一些流处理代码,它接受单词流并对它们执行一些操作,然后将它们缩减为Map包含单词作为键和单词作为Long值出现的次数.为了简洁代码,我使用了jOOL库Seq类,它包含许多有用的快捷方法.

如果我像这样编写它,代码编译就好了:

item.setWordIndex (
        getWords (item)                      // returns a Seq<String>
              .map (this::removePunctuation) // String -> String
              .map (stemmer::stem)           // String -> String
              .groupBy(str -> str, Collectors.counting ()));
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试str -> str用更多自我文档替换lambda Function::identity,我会收到以下错误:

setWordIndex(Map<String,Long>)类型中的方法MyClass不适用于参数(Map<Object,Long>)
类型Function没有定义identity(String)适用于此处

为什么我的Function::identity行为有任何不同str -> str,我(或许天真地)假设它是直接等价的,为什么编译器在使用它时不能处理它?

(是的,我知道我可以通过将先前的map应用程序移动到groupBy操作中来删除身份功能,但我发现代码更清晰,因为它更直接地遵循应用程序逻辑)

Oli*_*rth 7

您想要Function.identity()(返回a Function<T, T>),而不是Function::identity(与SAM类型匹配Supplier<Function<T, T>>).

以下代码编译正常:

static String removePunctuation(String x) { return x; }
static String stem(String x) { return x; }

// ...

final Map<String, Long> yeah = Seq.of("a", "b", "c")
        .map(Test::removePunctuation)
        .map(Test::stem)
        .groupBy(Function.identity(), Collectors.counting());
Run Code Online (Sandbox Code Playgroud)