我有一些流处理代码,它接受单词流并对它们执行一些操作,然后将它们缩减为Map
,其中包含单词作为键,单词的出现次数为{{1}价值。为了简化代码,我使用了jOOL library' Seq
类,其中包含许多有用的快捷方法。
如果我这样编写代码就编译得很好:
Long
但是,如果我尝试用更自我记录的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
lambda,我会收到以下错误:
Function::identity
类型中的方法setWordIndex(Map<String,Long>)
不适用于参数MyClass
类型(Map<Object,Long>)
未定义此处适用的Function
为什么identity(String)
与Function::identity
的行为有任何不同,我(或许是天真地)假设它是直接等价的,为什么编译器在使用它时可以处理它?</ p >
(是的,我知道我可以通过将先前的str -> str
应用程序移动到map
操作来删除身份功能,但我发现代码更清晰,因为它遵循应用程序逻辑更直接)
答案 0 :(得分:7)
您希望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());
答案 1 :(得分:2)
两种类型之间略有不同;它们不是直接等同的:
Function.identity()
必须返回输入类型,因为其类型为Function<T, T>
; str -> str
可以返回更广泛的类型;实际上是Function<? extends T, T>
。