Java 为什么可以';你不能检查这段代码吗?
我有一些流处理代码,它接受一个单词流并对其执行一些操作,然后将它们简化为一个Java 为什么可以';你不能检查这段代码吗?,java,generics,typechecking,Java,Generics,Typechecking,我有一些流处理代码,它接受一个单词流并对其执行一些操作,然后将它们简化为一个映射,其中包含作为键的单词,以及作为Long值的单词出现次数。为了代码的简洁性,我使用了的类,它包含许多有用的快捷方式方法 如果我这样编写代码,那么代码的编译效果很好: item.setWordIndex ( getWords (item) // returns a Seq<String> .map (this::remov
映射
,其中包含作为键的单词,以及作为Long
值的单词出现次数。为了代码的简洁性,我使用了的类,它包含许多有用的快捷方式方法
如果我这样编写代码,那么代码的编译效果很好:
item.setWordIndex (
getWords (item) // returns a Seq<String>
.map (this::removePunctuation) // String -> String
.map (stemmer::stem) // String -> String
.groupBy(str -> str, Collectors.counting ()));
item.setWordIndex(
getWords(item)//返回一个Seq
.map(this::removeparcing)//字符串->字符串
.map(stemmer::stem)//字符串->字符串
.groupBy(str->str,Collectors.counting());
但是,如果我试图用更自我记录的Function::identity
替换str->str
lambda,我会得到以下错误:
类型MyClass
中的方法setWordIndex(Map)
不适用于参数(Map)
类型
函数
未定义此处适用的标识(字符串)
为什么Function::identity
的行为与str->str
有任何不同,我(可能天真地)认为后者是直接等效的,为什么编译器在使用它时不能处理它
(是的,我知道我可以通过将以前的
map
应用程序移动到groupBy
操作中来删除identity函数,但我发现这样的代码更清晰,因为它更直接地遵循应用程序逻辑)这两种类型之间略有不同;它们不是直接等价的:
必须返回输入类型,因为其类型是Function.identity()
李>Function
可以返回更宽的类型;实际上,您想要的是str->str
Function函数
(返回Function.identity()
),而不是Function
(匹配SAM类型Function::identity
) 以下代码编译得很好:供应商
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());
您想要的静态字符串移除标点符号(字符串x){return x;} 静态字符串干(字符串x){return x;} // ... 最终地图yeah=序列号(“a”、“b”、“c”) .map(测试::删除标点符号) .map(测试::stem) .groupBy(Function.identity()、collector.counting());
而不是Function.identity()
@NimrodArgov的可能重复项-这个问题问的是在两者都起作用的情况下哪个更可取,而不是为什么Function::identity
在这种特定情况下不起作用。这让我想起了。也许我在这里提到的编译器选项会提供一些有用的见解?@AndyTurner-这很有趣。我猜这里的逻辑是在类似的行上工作的,但我不太清楚是如何工作的。虽然这是真的,但我不明白它在这里是如何相关的:使代码工作的正确类型是Function::identity
,因此,似乎不需要更广泛的类型?@Jules我只是指出,它们不是直接等价的。啊,是的。有道理,现在我再看一遍。:)函数