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
    ),而不是
    Function::identity
    (匹配SAM类型
    供应商

    以下代码编译得很好:

    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()
    而不是
    Function::identity
    @NimrodArgov的可能重复项-这个问题问的是在两者都起作用的情况下哪个更可取,而不是为什么
    Function::identity
    在这种特定情况下不起作用。这让我想起了。也许我在这里提到的编译器选项会提供一些有用的见解?@AndyTurner-这很有趣。我猜这里的逻辑是在类似的行上工作的,但我不太清楚是如何工作的。虽然这是真的,但我不明白它在这里是如何相关的:使代码工作的正确类型是
    函数
    ,因此,似乎不需要更广泛的类型?@Jules我只是指出,它们不是直接等价的。啊,是的。有道理,现在我再看一遍。:)