如何显式为Collector.of方法传递类型参数
如何显式为Collector.of方法传递类型参数
嗨,我来帮你解决这个显式指定Collector泛型参数的问题,同时也会排查你代码里的错误点~
首先,你遇到的ArrayList cannot be resolved、Collector cannot be resolved这类报错,主要有两个核心原因:
- 大概率是没导入必要的Java核心类(比如
java.util.stream.Collector、java.util.ArrayList、java.util.function.Function) - 显式指定泛型参数的语法完全写错了——
Collector的静态方法of的泛型参数,不能写在类名后面的尖括号里,而是要放在of方法名的前面!
正确的显式指定泛型的写法
先确保你在代码顶部导入了所有依赖的类:
import java.util.ArrayList; import java.util.Random; import java.util.function.Function; import java.util.stream.Collector;
然后修改Collector.of的调用方式,把泛型参数放在of方法的前面,紧跟Collector类名之后:
new Random().ints(200, 1, 200000) .boxed() // 这里是显式指定泛型参数的正确位置 .collect(Collector.<Integer, ArrayList<Integer>, ArrayList<Integer>>of( ArrayList<Integer>::new, (acc, i) -> { if (acc.size() > 4) { for (int ctr = acc.size() - 1; ctr >= 0; ctr--) { if (i > acc.get(ctr)) { acc.set(ctr, i); break; } } } else { acc.add(i); } }, (a, b) -> { // 注意:你原来的合并逻辑有问题!并行流时两个各5个元素的容器合并后会变成10个 // 这里必须额外处理:合并后重新筛选出最大的5个元素 a.addAll(b); // 降序排序后截取前5个 a.sort((x, y) -> Integer.compare(y, x)); if (a.size() > 5) { a.subList(5, a.size()).clear(); } return a; }, Function.identity(), Collector.Characteristics.IDENTITY_FINISH )) .forEach(System.out::println);
为什么原来的写法错误?
你之前尝试的Collector<Integer, ArrayList<Integer>, ArrayList<Integer>>.of(...)是典型的语法误用:
- 对于类的静态方法,泛型参数的指定格式是
类名.<泛型参数>方法名(...),要把泛型参数放在方法名的前面 - 类名后面加尖括号(比如
Collector<...>)是用来声明类的泛型实例的,而of是静态方法,不需要依赖实例,所以这种写法完全不适用
泛型参数的具体含义
这里指定的三个泛型参数对应Collector接口的三个类型参数:
- 第一个
Integer:流中每个元素的类型 - 第二个
ArrayList<Integer>:收集器的累加器类型(也就是中间过程中用来临时存储元素的容器类型) - 第三个
ArrayList<Integer>:收集器的最终结果类型(因为我们用了IDENTITY_FINISH特性,所以结果类型和累加器类型完全一致)
额外的逻辑修复
我还帮你修正了合并函数(combiner)的逻辑:你原来的代码只是简单合并两个容器的元素,但如果是并行流处理,两个各存5个元素的累加器合并后会有10个元素,这时候必须重新筛选出最大的5个,否则最终结果会不符合“取最大5个整数”的需求哦~
内容来源于stack exchange
相关产品推荐
相关产品推荐

