jdk8源码 collect

367 阅读2分钟

一.collect

1.collect:收集器

2.Collector作为collect方法的参数

3.Collector是一种接口,它是一个可变的汇聚操作,将输入元素累积到一个可变的结果容器中,它会在所有元素都处理完毕后,将累积的结果转换为一个最终的表示(这是一个可选操作);它支持串行与并行两种方式执行

4.Collectors本身提供了关于Collector的常见汇聚实现,Collectors本身实际上是一个工厂

5.Collector里有三个参数类型T,A,R(后续做补充)

6.Collector里面有四种参数方法

supplier,accumulator,combiner,finisher,在这里先主要写supplier和accumulator.


二. supplier

创建并返回一个可变结果容器;Supplier接口不接受参数并返回一个结果。

Supplier<A> supplier();

三.accumulator

将新的数据元素(包括集合)给合并到一个结果容器(将值给折叠到一个可变的结果容器当中,这个可变容器可以是输入元素中的的第一个元素(集合)也可以是新的集合)

BiConsumer接口 接受两个参数不返回值

BiConsumer<A,T> accumulator();

四.combiner

将两个结果容器给合并成一个

BinaryOperator接口 接受两个参数返回一个接果 这三个值为同类型

BinaryOperator<A> combiner();

五.finisher

对容器执行一个可选的最终转换

Function接口接受一个参数返回一个结果 两个值不是同类型

Function<A,R> finisher

六.统一性和结合性

为了保证串行流和并行流操作结果的等价性,需要collect函数满足两个条件,identity(同一性)和associativity(结合性)

identity:针对于任何部分累积的结果中,将它与一个空的中间容器的合并时,得到的结果与部分累积的结果一致(a== combiner.apply(a,supplier.get()))

(List<String>list1,List<String>list2) ->(list1.addAll(list2); return list1)

associativity:并行流分区分割计算的结果与串行流计算的结果也是一样的

针对与有序的collect 只要保证finisher.apply(a1).equals(finisher.apply(a2))是正确的就满足了结合性,如果是无序的collect,其中对于该规则就要求没那么严格,只要求他们具有相同的元素,而忽略了元素的排序。

reduce:对于集合里的操作的元素是不可变的,在串行流操作是没有影响,而在并行流使用时结果会出错(以后做详细补充)

collect:对于集合里的操作的元素是可变的

 七.Collector的参数类型

库基于Collector实现了reduction,需要遵守以下约束

Collector<T,A,R>

T:流操作中每一个参数的类型

A:累积中间操作生成的结果类型

R:汇聚操作的结果类型