本文目录#
Collector 架构#
Collector<T, A, R>
定义了流终端操作的聚合逻辑:
- Supplier:创建可变容器。
- Accumulator:将元素累加到容器。
- Combiner:并行流合并子结果。
- Finisher:将容器转换为最终结果。
- Characteristics:标识
UNORDERED
、CONCURRENT
、IDENTITY_FINISH
。
设计步骤#
- 明确需求:最终结果类型 R,是否需要中间容器。
- 选择容器:使用
ArrayList
、StringBuilder
或自定义对象。 - 定义 Accumulator:确保线程安全;在并行流下不要对共享状态写操作。
- Combiner:合并两个容器;对串行流会被优化掉,但必须正确实现。
- Finisher:如果容器即结果,返回
collectorOf(..., Characteristics.IDENTITY_FINISH)
。
示例:计算 Top-K 热门元素#
1 | class TopKCollector<T> implements Collector<T, PriorityQueue<T>, List<T>> { |
线程安全注意事项#
- 避免在
accumulator
中使用共享可变状态。 - 如果容器不是线程安全的,Collector 不能声明为
CONCURRENT
。 - 使用并行流时确保组合操作对数据无副作用。
自检清单#
- 是否正确实现
combiner
,在并行流下能合并结果? - 是否根据容器是否等于结果设置
IDENTITY_FINISH
? - 是否评估并行流执行效率与线程安全?
参考资料#
- Java SE 8 API -
Collector
接口:https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html - Oracle Stream API 指南:https://docs.oracle.com/javase/tutorial/collections/streams/index.html
- 《Effective Java》第 7 章 Stream 最佳实践
本作品系原创,采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,转载请注明出处。