收集器接口
你可以为Collectors接口提供自己的实现,从而自由地创建自定义归约操作。
public interface Collector<T, A, R> {
Supplier<A> supplier();
BiConsumer<A, T> accumulator();
Function<A, R> finisher();
BinaryOperator<A> combiner();
Set<Characteristics> characteristics();
}
本列表使用一下定义:
- T 是流中要收集的项目的泛型
- A 是累加器的类型,累加器是在收集过程中用于累积部分结果的对象。
- R 是收集操作得到的对象(通常但不一定是集合)的类型。
例如你可以实现一个ToListCollector类,将Stream中的所有元素收集到一个List里,它的签名如下:
public class ToListCollector<T> implements Collector<T, List<T>, List<T>>
理解Collector 接口声明的方法
前四个方法都会返回一个被collect方法调用的函数,而第五个方法characteristics则提供了一系列特征,也就是一个提示列表,告诉collect方法在执行归约操作的时候可以应用哪些优化(比如并行化)。
1.建立新的结果容器:supplier方法
supplier方法必须返回一个结果为空的Supplier,也就是一个无参数函数,在调用时他会创建一个空的累加器实例,供数据收集过程使用。
对于将累加器本身作为结果返回的收集器,比如我们的ToListCollector,在对空流执行操作的时候,这个空的累加器也代表了收集过程的结果,在我们的ToListCollector中,supplier返回一个空的List
public Supplier<List<T>> supplier() {
return ArrayList::new;
}
2. 将元素添加到结果容器:accumulator方法
accumulator(积聚者、收集器)方法会返回执行归约操作的函数。当遍历到流中第n个元素时,这个函数执行时会有两个参数:保存归约结果的累加器(已收集了流中的前n-1个项目),还有第n个元素本身。该函数将返回void,因为累加器是原位更新,即函数的执行改变了它的内部状态以体现