Java Stream Collect分类器无法识别类型:键为何不是String?
问题解答
原因分析
Java编译器在处理嵌套的groupingByConcurrent结合并行流时,类型推断能力受限,无法自动识别split("\\s+")返回的String[]数组中元素的类型。虽然split方法明确返回String[],但在链式调用的lambda表达式中,编译器无法准确推导arr -> arr[0]和arr -> arr[arr.length-1]这两个lambda返回值的类型,最终将键的类型推断为Object,导致返回类型变成ConcurrentMap<Object, ConcurrentMap<Object, Long>>。
解决方案
通过显式指定lambda参数的类型,帮助编译器明确数组的类型为String[],从而确定键的类型是String。修改后的代码如下:
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( (String[] arr) -> arr[0], // 显式指定arr为String[] Collectors.groupingByConcurrent( (String[] arr) -> arr[arr.length-1], // 显式指定arr为String[] Collectors.counting() ) ) ); } catch (IOException e) { throw new UncheckedIOException(e); }
修改后,编译器就能正确推断出返回类型为ConcurrentMap<String, ConcurrentMap<String, Long>>,而ConcurrentMap是Map的子接口,完全符合你预期的Map<String, Map<String, Long>>返回类型要求。
内容的提问来源于stack exchange,提问作者pandaoverflow
相关产品推荐
相关产品推荐

