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

问题描述 投票:0回答:2

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

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

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::identitystr -> str有任何不同,我(也许是天真的)假设它是直接等价的,为什么编译器在使用它时不能处理它?

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

java generics typechecking
2个回答
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());

2
投票

这两种类型略有不同;它们不是直接等价的:

  • Function.identity()必须返回输入类型,因为它的类型是Function<T, T>;
  • str -> str可以返回更广泛的类型;实际上它是Function<? extends T, T>
© www.soinside.com 2019 - 2024. All rights reserved.