mutable reduction operation将输入元素累积到可变结果容器中,可选地在处理完所有输入元素后将累积结果转换为最终表示。 还原操作可以顺序执行或并行执行。

可变还原操作的示例包括:将元素累积到Collection ; 使用StringBuilder连接字符串; 计算有关元素的摘要信息,例如总和,最小值,最大值或平均值; 计算“枢轴表”摘要,例如“卖方的最大价值交易”等。类Collectors提供了许多常见的可变减少的实现。

Collector由四个函数指定,这四个函数一起工作以将条目累积到可变结果容器中,并且可选地对结果执行最终转换。 他们是:

  • 创建新的结果容器( supplier()
  • 将新数据元素合并到结果容器中( accumulator()
  • 将两个结果容器合并为一个( combiner()
  • 在容器上执行可选的最终转换( finisher()

收集器还具有一组特征,例如Collector.Characteristics.CONCURRENT ,它们提供可以由缩减实现使用以提供更好性能的提示。

使用收集器顺序实现缩减将使用supplier函数创建单个结果容器,并为每个输入元素调用一次累加器函数。 并行实现将对输入进行分区,为每个分区创建结果容器,将每个分区的内容累积到该分区的子结果中,然后使用组合器函数将子结果合并为组合结果。

为确保顺序和并行执行产生相同的结果,收集器函数必须满足标识associativity约束。

标识约束表示对于任何部分累积的结果,将其与空结果容器组合必须产生等效结果。 也就是说,对于部分累积结果a ,它是任何一系列累加器和组合器调用的结果, a必须等效于combiner.apply(a, supplier.get())

关联约束表示拆分计算必须产生等效结果。 也就是说,对于任何输入元素t1t2 ,以下计算中的结果r1r2必须是等效的:

 A a1 = supplier.get(); accumulator.accept(a1, t1); accumulator.accept(a1, t2); R r1 = finisher.apply(a1); // result without splitting A a2 = supplier.get(); accumulator.accept(a2, t1); A a3 = supplier.get(); accumulator.accept(a3, t2); R r2 = finisher.apply(combiner.apply(a2, a3)); // result with splitting  

对于不具备收藏UNORDERED特征,两名积累的结果a1a2是等价的,如果finisher.apply(a1).equals(finisher.apply(a2)) 对于无序收集器,放宽等价以允许与顺序差异相关的不相等。 (例如,向List累积元素的无序收集器会考虑两个等效的列表,如果它们包含相同的元素,则忽略顺序。)

基于Collector实现减少的Collector ,例如Stream.collect(Collector) ,必须遵守以下约束:

  • 第一个参数传递给累加器函数,两个参数都传递给组合器函数,传递给整理器函数的参数必须是先前调用结果供应商,累加器或组合器函数的结果。
  • 除了将它们再次传递给累加器,组合器或修整器功能,或者将它们返回到缩减操作的调用者之外,该实现不应对任何结果提供者,累加器或组合器函数的结果做任何事情。
  • 如果结果传递给组合器或修整器功能,并且不从该功能返回相同的对象,则永远不会再次使用它。
  • 一旦结果传递给组合器或修整器功能,它就不会再次传递给累加器功能。
  • 对于非并发收集器,从结果提供者,累加器或组合器函数返回的任何结果必须是串行线程限制的。 这使得收集能够并行发生,而Collector不需要实现任何其他同步。 减少实现必须管理输入被正确分区,分区是单独处理的,并且只有在累积完成后才进行组合。
  • 对于并发收集器,实现可以(但不是必须)同时实现还原。 并发减少是使用相同的可同时修改的结果容器从多个线程同时调用累加器函数的减少,而不是在累积期间保持结果被隔离。 仅当收集器具有Collector.Characteristics.UNORDERED特征或原始数据无序时,才应应用并发减少。

除了Collectors中的预定义实现之外 ,静态工厂方法of(Supplier, BiConsumer, BinaryOperator, Characteristics...)可用于构造收集器。 例如,您可以创建一个收集器,将小部件累积到TreeSet中:

 Collector<Widget, ?, TreeSet<Widget>> intoSet = Collector.of(TreeSet::new, TreeSet::add, (left, right) -> { left.addAll(right); return left; });  
(此行为也由预定义收集器Collectors.toCollection(Supplier)实现 )。 指示 Collector属性的 Collector ,可用于优化缩减实现。 将值折叠到可变结果容器中的函数。 返回 SetCollector.Characteristics指示此收集器的特征。 一个接受两个部分结果并合并它们的函数。 执行从中间累积类型 A到最终结果类型 R的最终 R 。 返回一个新 Collector由给定的描述 supplieraccumulatorcombinerfinisher功能。 返回一个新 Collector由给定的描述 supplieraccumulatorcombiner功能。 一个创建并返回新的可变结果容器的函数。 一个创建并返回新的可变结果容器的函数。 将值折叠到可变结果容器中的函数。 一个接受两个部分结果并合并它们的函数。 组合器函数可以将状态从一个参数折叠到另一个参数并返回该参数,或者可以返回新的结果容器。 执行从中间累积类型A到最终结果类型R的最终R

如果设置了特征IDENTITY_FINISH ,则可以假定该函数是具有从AR的未检查的A转换的身份变换。

返回SetCollector.Characteristics指示此收集器的特征。 这个集合应该是不可变的。 返回一个新Collector由给定的描述supplieraccumulatorcombiner功能。 由此产生的Collector具有Collector.Characteristics.IDENTITY_FINISH特征。 返回一个新 Collector由给定的描述 supplieraccumulatorcombinerfinisher功能。
嵌套类  
变量和类型 接口 描述
static class  Collector.Characteristics
指示 Collector属性的 Collector ,可用于优化缩减实现。
所有方法  静态方法  实例方法 抽象方法 
变量和类型 方法 描述
BiConsumer<A,​T> accumulator()
将值折叠到可变结果容器中的函数。
Set<Collector.Characteristics> characteristics()
返回 SetCollector.Characteristics指示此收集器的特征。
BinaryOperator<A> combiner()
一个接受两个部分结果并合并它们的函数。
Function<A,​R> finisher()
执行从中间累积类型 A到最终结果类型 R的最终 R
static <T,​A,​R>
Collector<T,​A,​R>
of​(Supplier<A> supplier, BiConsumer<A,​T> accumulator, BinaryOperator<A> combiner, Function<A,​R> finisher, Collector.Characteristics... characteristics)
返回一个新 Collector由给定的描述 supplieraccumulatorcombinerfinisher功能。
static <T,​R>
Collector<T,​R,​R>
of​(Supplier<R> supplier, BiConsumer<R,​T> accumulator, BinaryOperator<R> combiner, Collector.Characteristics... characteristics)
返回一个新 Collector由给定的描述 supplieraccumulatorcombiner功能。
Supplier<A> supplier()
一个创建并返回新的可变结果容器的函数。