Collector接口是Stream收集器的核心契约,Collectors工具类返回其具体实现;它定义supplier、accumulator、combiner、finisher和characteristics五个方法,分别对应收集四阶段及特性声明,支持标准与自定义收集逻辑。

Java 8 的 Stream 收集器(Collectors)本身不直接“实现接口”,而是通过函数式接口(如 Supplier、BiConsumer、BinaryOperator、Function)来定义行为。真正与接口配合的关键,在于 Collector 接口本身 —— 它是所有收集器的契约,而 Collectors 工具类返回的实例,都是该接口的具体实现。
Collector 接口是核心桥梁
Collector<t a r></t> 是一个泛型函数式接口,定义了五个抽象方法,分别对应收集过程的四个阶段和一个特征描述:
-
supplier():提供一个可变容器(如ArrayList::new),类型为Supplier<a></a> -
accumulator():将每个流元素累加进容器,类型为BiConsumer<a t></a> -
combiner():合并两个并行子任务的中间结果,类型为BinaryOperator<a></a> -
finisher():将中间容器A转为最终结果R(如把ArrayList包装成不可变List),类型为Function<a r></a> -
characteristics():声明收集器特性(如CONCURRENT、UNORDERED),影响并行执行策略
标准收集器如何体现接口协作
当你写 .collect(Collectors.toList()),实际返回的是一个内部 CollectorImpl 实例,它实现了 Collector 接口,并用 Lambda 或方法引用填充了上述函数式接口参数:
-
supplier→() -> new ArrayList() -
accumulator→(list, t) -> list.add(t) -
combiner→(list1, list2) -> { list1.addAll(list2); return list1; } -
finisher→Function.identity()(因为ArrayList就是最终需要的List)
这些函数式接口让收集逻辑完全解耦,也使自定义收集器只需按接口规范实现,无需关心 Stream 内部调度。
立即学习“Java免费学习笔记(深入)”;
自定义收集器必须实现 Collector 接口
若标准方法无法满足需求(比如要收集为 Guava 的 ImmutableList 或统计带权重的平均值),就必须手动实现 Collector 接口:
- 定义泛型参数:
Collector<student doublesummarystatistics double></student>可用于加权平均 - 在
accumulator中编写带权重的累加逻辑 - 利用
characteristics声明CONCURRENT,启用并行安全合并
这种实现方式不是“对接口的调用”,而是“对接口的实现”——它让 Stream 引擎能统一识别、调度、优化你的逻辑。
业务接口与收集器协同的常见模式
实际开发中,常把领域接口与收集器结合使用,提升可读性与复用性:
- 用
Function<order string></order>提取订单号:Collectors.toMap(Order::getId, Function.identity()) - 用
Predicate<user></user>配合partitioningBy分区:Collectors.partitioningBy(User::isActive) - 自定义接口作为收集目标,例如
ReportSummary,再通过Collectors.collectingAndThen(..., ReportSummary::new)封装
这里接口的作用是明确数据契约,而收集器负责按契约组装数据,二者分工清晰。


















