jdk8 stream - collector类

 

collect这个类提供了一个对于stream的可改变的精简操作,就是可以多个输入的元素累计到一个可变的结果容器内,当所有的元素都被处理过了之后还可以决定是否要将这个可变的容器转型到一个最终的容器中,这一步的操作可以做也可以不做。对stream的精简操作可以是串行化的也可以是并行化的。

精简操作例如:将元素累计到一个容器内,将字符串拼接到一个StringBuilder里,计算元素的加减操作,最大值最小值操作等等,collects类提供了很多通用的操作。

 

collect指定了由4个函数方法共同协作来处理元素并将它们添加到一个可变的结果容器中,其中对结果容器的最终转换这一步骤是可选的。

1.  创建一个新的结果容器  supplier()

2.  合并一个新的元素到结果容器中  accumulator()

3.  合并两个结果容器为一个新的结果容器 combiner()

4.  对最终的结果容器进行转化 ,可选的操作   finisher()

collects有一些特性,比如 Collector.Characteristics.CONCURRENT, 表示精简操作会被多个线程并发执行会提高效率。

 

 

对于串行化的处理,只会创建一个单一的结果容器,每次对于输入元素的处理后就将结果放入这个结果容器内,如果是并行化操作,对于每个分区就会创建一个结果容器,将每个分区的操作结果放入自己的结果容器内部,然后使用combine函数将这些子结果容器合并为一个结果容器。

为了确保串行和并行执行的结果相同,collect的函数必须满足一个表示和其相关联的限定。

对于输入元素的处理结果合并到结果容器内就是   combiner.apply(a, supplier.get()).

所结合的限制性条件是为了确保分区计算结果正确。例如对于任何的输入元素他 t1 和 t2 ,一下的方式是等价的。

 

 

对于无序的collects拥有 UNORDERED  的特性,也就是两个累计的结果容器  finisher.apply(a1).equals(finisher.apply(a2))。

基于collect的精简操作实现,例如   Stream.collect(Collector), 必须附加如下的限定:

1.  传递给accumulator函数的第一个参数,传递给combiner函数的两个函数和传递给finisher的参数必须是之前先调用的supplier,accumulator,combiner函数的执行结果。

2.  实现不应该对supplier提供的结果容器,accumulator,combiner的结果做任何处理,除非是将它们传递给accumulator,combiner,finisher或者直接传递给调用者。

3.  如果一个将一个执行结果传递给了combiner或者finisher,但是这个对象没有被返回,那么它就不会再被使用了。

4.  一旦一个执行结果传递给了combiner或者finisher,它就不会再被传递给accumulator了。(一个输入元素不会被消耗两次)

5.  对于非并发的collector,从supplier,accumulator,combiner返回的结果是受串行线程限制的。这使得对集合的操作可以并行执行而不需要对collector添加额外的synchronization。精简操作的实现必须确保分区是否正确,是否单独处理,并且只要在accumulator完成之后才能进行combiner操作。

6.  对于并发的collectors,实现可以自由的(不必须的)并发实现精简操作。并发精简操作是指一个accumulator操作可以被多个线程同时调用,使用相同的可同时并发修改的结果容器而不是在accumulator的阶段使结果隔离。只有当collector具有Collector.Characteristics.UNORDERED特性或者原始数据无序的时候,这个并发精简操作才可以被调用。

 

 

除了collectors里预定义的实现之外,静态的工厂方法(Supplier, BiConsumer, BinaryOperator, Characteristics...) 也可以用来构建collectors,

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值