Java Stream Collect() 分类器无法检测类型



我从文本文件中读取了以下代码行:

try (BufferedReader br = new BufferedReader(new InputStreamReader(Uio.decodeFrom(url)))) {
return br.lines()
.parallel()
.map(s -> s.split("\s+")) // split by whitespace
.collect(
Collectors.groupingByConcurrent(
arr -> arr[0], // String 1
Collectors.groupingByConcurrent(
arr -> arr[arr.length-1], // String 2
Collectors.counting()
)
)
);
} catch (IOException e) {
throw new UncheckedIOException(e);
}

文本文件包含类似的数据

String1     ... cols      ... String2
string1data ... otherdata ... string2data
...

我正在尝试按String1String2进行分组,并得到它们的计数。那么最终结果应该是Map<String, Map<String, Long>>。但是,对于上面的代码,编译器表示collect()返回一个ConcurrentMap <Object, ConcurrentMap<Object, Long>>

为什么键不是字符串?

我可以复制此错误消息,但在错误消息中将String替换为Object似乎是在转移注意力。真正的问题是Java的泛型是不变的。

如果对collect的调用返回的是ConcurrentMap<String, ConcurrentMap<String, Long>>,则这与Map<String, Map<String, Long>>不匹配,即使ConcurrentMapMap。内部Map类型必须完全匹配,不包含通配符和边界。

如果在返回类型中引入一个上界通配符,则编译时不会出错。让它返回类型Map<String, ? extends Map<String, Long>>,这样内部的ConcurrentMap<String, Long>就会匹配。

返回类型Map<String, ConcurrentMap<String, Long>>也将起作用。

在解决泛型不变问题之前,还不清楚为什么String没有被捕获。只是猜测:编译器还没有捕获String,因为它首先发现了不变泛型问题。一旦不变泛型问题得到解决,它就会编译而不会出错,这意味着String确实得到了推断。

最新更新