-
- 参数类型
-
T
- 缩小操作的输入元素的类型 -
A
- 还原操作的可变累积类型(通常隐藏为实现细节) -
R
- 缩小操作的结果类型
public interface Collector<T,A,R>
mutable reduction operation将输入元素累积到可变结果容器中,可选地在处理完所有输入元素后将累积结果转换为最终表示。 还原操作可以顺序执行或并行执行。可变还原操作的示例包括:将元素累积到
Collection
; 使用StringBuilder
连接字符串; 计算有关元素的摘要信息,例如总和,最小值,最大值或平均值; 计算“枢轴表”摘要,例如“卖方的最大价值交易”等。类Collectors
提供了许多常见的可变减少的实现。Collector
由四个函数指定,这四个函数一起工作以将条目累积到可变结果容器中,并且可选地对结果执行最终转换。 他们是:- 创建新的结果容器(
supplier()
) - 将新数据元素合并到结果容器中(
accumulator()
) - 将两个结果容器合并为一个(
combiner()
) - 在容器上执行可选的最终转换(
finisher()
)
收集器还具有一组特征,例如
Collector.Characteristics.CONCURRENT
,它们提供可以由缩减实现使用以提供更好性能的提示。使用收集器顺序实现缩减将使用supplier函数创建单个结果容器,并为每个输入元素调用一次累加器函数。 并行实现将对输入进行分区,为每个分区创建结果容器,将每个分区的内容累积到该分区的子结果中,然后使用组合器函数将子结果合并为组合结果。
为确保顺序和并行执行产生相同的结果,收集器函数必须满足标识和associativity约束。
标识约束表示对于任何部分累积的结果,将其与空结果容器组合必须产生等效结果。 也就是说,对于部分累积结果
a
,它是任何一系列累加器和组合器调用的结果,a
必须等效于combiner.apply(a, supplier.get())
。关联约束表示拆分计算必须产生等效结果。 也就是说,对于任何输入元素
t1
和t2
,以下计算中的结果r1
和r2
必须是等效的: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
特征,两名积累的结果a1
和a2
是等价的,如果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)
实现 )。- API Note:
- 使用
Collector
执行缩减操作应产生相当于以下结果的结果:R container = collector.supplier().get(); for (T t : data) collector.accumulator().accept(container, t); return collector.finisher().apply(container);
但是,库可以自由分区输入,对分区执行缩减,然后使用组合器功能组合部分结果以实现并行缩减。 (根据具体的减速操作,这可能会更好或更差,具体取决于累加器和组合器功能的相对成本。)
收藏家的目的是组成 ;
Collectors
中的许多方法都是采用收集器并生成新收集器的函数。 例如,给定以下收集器来计算员工流的工资总和:Collector<Employee, ?, Integer> summingSalaries = Collectors.summingInt(Employee::getSalary))
Collectors.groupingBy(Function, Collector)
重用“工资总和”逻辑:Collector<Employee, ?, Map<Department, Integer>> summingSalariesByDept = Collectors.groupingBy(Employee::getDepartment, summingSalaries);
- 从以下版本开始:
- 1.8
- 另请参见:
-
Stream.collect(Collector)
,Collectors
-
-
嵌套类汇总
嵌套类 变量和类型 接口 描述 static class
Collector.Characteristics
指示Collector
属性的Collector
,可用于优化缩减实现。
-
方法摘要
所有方法 静态方法 实例方法 抽象方法 变量和类型 方法 描述 BiConsumer<A,T>
accumulator()
将值折叠到可变结果容器中的函数。Set<Collector.Characteristics>
characteristics()
返回Set
的Collector.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
由给定的描述supplier
,accumulator
,combiner
和finisher
功能。static <T,R>
Collector<T,R,R>of(Supplier<R> supplier, BiConsumer<R,T> accumulator, BinaryOperator<R> combiner, Collector.Characteristics... characteristics)
返回一个新Collector
由给定的描述supplier
,accumulator
和combiner
功能。Supplier<A>
supplier()
一个创建并返回新的可变结果容器的函数。
-
-
-
方法详细信息
-
accumulator
BiConsumer<A,T> accumulator()
将值折叠到可变结果容器中的函数。- 结果
- 将值折叠到可变结果容器中的函数
-
combiner
BinaryOperator<A> combiner()
一个接受两个部分结果并合并它们的函数。 组合器函数可以将状态从一个参数折叠到另一个参数并返回该参数,或者可以返回新的结果容器。- 结果
- 将两个部分结果组合成组合结果的函数
-
finisher
Function<A,R> finisher()
执行从中间累积类型A
到最终结果类型R
的最终R
。如果设置了特征
IDENTITY_FINISH
,则可以假定该函数是具有从A
到R
的未检查的A
转换的身份变换。- 结果
- 将中间结果转换为最终结果的函数
-
characteristics
Set<Collector.Characteristics> characteristics()
返回Set
的Collector.Characteristics
指示此收集器的特征。 这个集合应该是不可变的。- 结果
- 一组不可变的收集器特征
-
of
static <T,R> Collector<T,R,R> of(Supplier<R> supplier, BiConsumer<R,T> accumulator, BinaryOperator<R> combiner, Collector.Characteristics... characteristics)
返回一个新Collector
由给定的描述supplier
,accumulator
和combiner
功能。 由此产生的Collector
具有Collector.Characteristics.IDENTITY_FINISH
特征。- 参数类型
-
T
- 新收集器的输入元素的类型 -
R
- 新收集器的中间累积结果类型和最终结果 - 参数
-
supplier
- 新收集器的供应商功能 -
accumulator
- 新收集器的累加器功能 -
combiner
- 新收集器的组合器功能 -
characteristics
- 新收集器的收集器特性 - 结果
- 新的
Collector
- 异常
-
NullPointerException
- 如果任何参数为null
-
of
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
由给定的描述supplier
,accumulator
,combiner
和finisher
功能。- 参数类型
-
T
- 新收集器的输入元素的类型 -
A
- 新收集器的中间累积类型 -
R
- 新收集器的最终结果类型 - 参数
-
supplier
- 新收集器的供应商功能 -
accumulator
- 新收集器的累加器功能 -
combiner
- 新收集器的组合器功能 -
finisher
- 新收集器的装订器功能 -
characteristics
- 新收集器的收集器特性 - 结果
- 新的
Collector
- 异常
-
NullPointerException
- 如果任何参数为null
-
-