我有一些流处理代码,它接受一个单词流并对它们执行一些操作,然后将它们缩减为包含单词作为键的Map
以及单词作为Long
值出现的次数。为了简洁代码,我使用了jOOL library的Seq
类,它包含许多有用的快捷方法。
如果我像这样编写它,代码编译就好了:
item.setWordIndex (
getWords (item) // returns a Seq<String>
.map (this::removePunctuation) // String -> String
.map (stemmer::stem) // String -> String
.groupBy(str -> str, Collectors.counting ()));
但是,如果我尝试用更自我记录的str -> str
替换Function::identity
lambda,我会收到以下错误:
setWordIndex(Map<String,Long>)
类型中的方法MyClass
不适用于(Map<Object,Long>)
论证 类型Function
没有定义适用于此的identity(String)
为什么Function::identity
与str -> str
有任何不同,我(也许是天真的)假设它是直接等价的,为什么编译器在使用它时不能处理它?
(是的,我知道我可以通过将之前的map
应用程序移动到groupBy
操作中来删除身份功能,但我发现代码更清晰,因为它更直接地遵循应用程序逻辑)
你想要Function.identity()
(返回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());
这两种类型略有不同;它们不是直接等价的:
Function.identity()
必须返回输入类型,因为它的类型是Function<T, T>
;str -> str
可以返回更广泛的类型;实际上它是Function<? extends T, T>
。