为什么不能 Java 对这段代码进行类型检查?
Why can't Java typecheck this code?
我有一些流处理代码,它接受单词流并对它们执行一些操作,然后将它们缩减为 Map
,其中包含单词作为键,单词出现的次数作为 Long
值。为了代码的简洁,我使用了jOOL library's Seq
class,里面包含了一些有用的快捷方式
如果我这样写,代码编译得很好:
item.setWordIndex (
getWords (item) // returns a Seq<String>
.map (this::removePunctuation) // String -> String
.map (stemmer::stem) // String -> String
.groupBy(str -> str, Collectors.counting ()));
但是,如果我尝试用更自记录的 Function::identity
替换 str -> str
lambda,我会收到以下错误:
The method setWordIndex(Map<String,Long>)
in the type MyClass
is not applicable for the arguments (Map<Object,Long>)
The type Function
does not define identity(String)
that is applicable here
为什么 Function::identity
的行为与 str -> str
有任何不同,我(也许天真地)假设它是直接等效的,为什么编译器在使用时不能处理它?
(是的,我知道我可以通过将之前的 map
应用程序移动到 groupBy
操作中来删除身份函数,但我发现这样的代码更清晰,因为它遵循更直接的应用程序逻辑)
两种类型之间存在细微差别;它们并不直接等价:
Function.identity()
必须 return 输入类型,因为它的类型是 Function<T, T>
;
str -> str
可以 return 更宽的类型;实际上它是 Function<? extends T, T>
.
你想要Function.identity()
(returns一个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());
我有一些流处理代码,它接受单词流并对它们执行一些操作,然后将它们缩减为 Map
,其中包含单词作为键,单词出现的次数作为 Long
值。为了代码的简洁,我使用了jOOL library's Seq
class,里面包含了一些有用的快捷方式
如果我这样写,代码编译得很好:
item.setWordIndex (
getWords (item) // returns a Seq<String>
.map (this::removePunctuation) // String -> String
.map (stemmer::stem) // String -> String
.groupBy(str -> str, Collectors.counting ()));
但是,如果我尝试用更自记录的 Function::identity
替换 str -> str
lambda,我会收到以下错误:
The method
setWordIndex(Map<String,Long>)
in the typeMyClass
is not applicable for the arguments(Map<Object,Long>)
The typeFunction
does not defineidentity(String)
that is applicable here
为什么 Function::identity
的行为与 str -> str
有任何不同,我(也许天真地)假设它是直接等效的,为什么编译器在使用时不能处理它?
(是的,我知道我可以通过将之前的 map
应用程序移动到 groupBy
操作中来删除身份函数,但我发现这样的代码更清晰,因为它遵循更直接的应用程序逻辑)
两种类型之间存在细微差别;它们并不直接等价:
Function.identity()
必须 return 输入类型,因为它的类型是Function<T, T>
;str -> str
可以 return 更宽的类型;实际上它是Function<? extends T, T>
.
你想要Function.identity()
(returns一个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());