pan*_*low 6 java collections java-stream
我有以下代码从文本文件读取行:
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);
}
Run Code Online (Sandbox Code Playgroud)
文本文件包含如下数据
String1 ... cols ... String2
string1data ... otherdata ... string2data
...
Run Code Online (Sandbox Code Playgroud)
我正在尝试按 和 进行分组String1并String2获取它们的计数。那么最终结果应该是一个Map<String, Map<String, Long>>. 然而,对于上面的代码,编译器说返回collect()一个 ConcurrentMap <Object, ConcurrentMap<Object, Long>>.
为什么键不是字符串?
String我可以复制此错误消息,但错误消息中的替换Object似乎是转移注意力。真正的问题是Java 的泛型是不变的。
如果对的调用collect返回 a ,则即使 a是 a ,ConcurrentMap<String, ConcurrentMap<String, Long>>也不匹配。内部类型必须完全匹配,没有通配符和边界。Map<String, Map<String, Long>>ConcurrentMapMapMap
如果您向返回类型引入上限通配符,它将编译而不会出现错误。让它返回 type Map<String, ? extends Map<String, Long>>,以便内部ConcurrentMap<String, Long>匹配。
返回类型Map<String, ConcurrentMap<String, Long>>也可以工作。
目前还不清楚为什么String在解决泛型不变问题之前没有被捕获。只是猜测:编译器尚未捕获String,因为它首先发现了不变泛型问题。一旦解决了不变泛型问题,它就可以正确编译,这意味着确实String可以推断出来。