Java Stream中Collector内的类型推断问题及解决方法
问题:链式调用时Collector类型推断失败导致编译错误
场景:实现相邻重复元素分组的收集逻辑,若不将collect结果赋值给List<List<String>>变量,直接链式调用stream()会出现类型不匹配编译错误;但赋值给变量后则正常编译。
原代码示例
public static void main(String args[]) { List<String> input = Arrays.asList("RED", "RED", "BLUE", "BLUE", "BLUE", "BLUE", "RED", "RED"); List<List<String>> output = // 注释该行则无法编译 input.stream() .collect(Collector.of( ArrayList::new, (accumulator, item) -> { if (accumulator.isEmpty()) { List<String> list = new ArrayList<>(); list.add(item); accumulator.add(list); } else { List<String> last = accumulator.get(accumulator.size() - 1); if (last.isEmpty() || last.get(0).equals(item)) { last.add(item); } else { List<String> list = new ArrayList<>(); list.add(item); accumulator.add(list); } } }, (left, right) -> { left.addAll(right); return left; } )); }
期望的链式调用方式:
input.stream() .collect(Collector.of(.....)) .stream() // 后续操作
编译错误原因
Java编译器的类型推断能力在链式调用场景下存在限制:
- 当将
collect结果赋值给List<List<String>>变量时,变量的显式类型会帮助编译器推断Collector.of的三个泛型参数:T=String(流元素类型)、A=ArrayList<List<String>>(累加器类型)、R=List<List<String>>(最终结果类型)。 - 若直接链式调用
stream(),编译器无法从后续的stream()方法反推collect的返回类型,导致Collector.of的泛型参数推断不完整,最终认为返回类型不明确,无法匹配stream()方法的调用要求。
解决方法
方法1:显式指定Collector的泛型参数
通过显式声明Collector.of的泛型参数,让编译器明确收集器的输入、累加器和输出类型,链式调用时即可正确识别返回值类型:
input.stream() .collect(Collector.<String, ArrayList<List<String>>, List<List<String>>>of( ArrayList::new, (accumulator, item) -> { if (accumulator.isEmpty()) { List<String> list = new ArrayList<>(); list.add(item); accumulator.add(list); } else { List<String> last = accumulator.get(accumulator.size() - 1); if (last.isEmpty() || last.get(0).equals(item)) { last.add(item); } else { List<String> list = new ArrayList<>(); list.add(item); accumulator.add(list); } } }, (left, right) -> { left.addAll(right); return left; } )) .stream() // 示例后续操作:打印每个分组 .forEach(group -> System.out.println(group));
方法2:临时类型转换(简洁但可读性稍弱)
在collect结果后添加显式类型转换,直接告诉编译器返回值的类型:
((List<List<String>>) input.stream() .collect(Collector.of(.....))) .stream() // 后续操作
推荐使用方法1,显式泛型参数的方式代码逻辑更清晰,可读性更高。
内容的提问来源于stack exchange,提问作者bbKing
相关产品推荐
相关产品推荐

