您当前的位置: 首页 > 

梁云亮

暂无认证

  • 3浏览

    0关注

    1211博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Stream API ---- 收集器Collector

梁云亮 发布时间:2019-11-11 01:17:02 ,浏览量:3

Stream API ---- 收集器Collector 转换方法collect()

毫不夸张的讲,如果发现某个功能在Stream接口中没找到,十有八九可以通过collect()方法实现。collect()是Stream接口方法中最灵活的一个,学会它才算真正入门Java函数式编程。

收集器Collector

收集器(Collector)是为Stream.collect()方法量身打造的工具接口,它是一种通用的、从流生成复杂值的结构。只要将它传给collect方法,所有的流就都可以使用它生成想要的数据结构了。

Collector是Stream的可变减少操作接口,可变减少操作包括:将元素累积到集合中、使用StringBuilder连接字符串、计算元素相关的统计信息(sum,min,max或average)等。

Collector接受三个泛型参数,对可变减少操作的数据类型作相应限制:

  • T:输入元素类型
  • A:缩减操作的可变累积类型(通常隐藏为实现细节)
  • R:可变减少操作的结果类型

Collector接口声明了4个函数,这四个函数一起协调执行以将元素累积到可变结果容器中,并且可以选择地对结果进行最终的变换:

  • Supplier supplier():创建新的结果
  • BiConsumer accumulator():将元素添加到结果容器
  • BinaryOperator combiner():将两个结果容器合并为一个结果容器
  • Function finisher():对结果容器作相应的变换

在Collector接口的characteristics方法内,可以对Collector声明相关约束,有关该方法的声明如下:

Set characteristics():

Characteristics是Collector内的一个枚举类,它声明了以下三个属性,用来约束Collector的属性:

  • CONCURRENT:表示此收集器支持并发,意味着允许在多个线程中,累加器可以调用结果容器
  • UNORDERED:表示收集器并不按照Stream中的元素输入顺序执行
  • IDENTITY_FINISH:表示finisher实现的是识别功能,可忽略。

注:如果一个容器仅声明CONCURRENT属性,而不是UNORDERED属性,那么该容器仅仅支持无序的Stream在多线程中执行。

Stream可以顺序执行、并发执行或者顺序并发执行,为了保证Stream可以产生相同的结果,收集器函数必须满足身份约束和相关项约束。

  • 身份约束:对于任何部分累积的结果,将其与空结果容器组合必须产生等效结果。即,对于作为任何系列的累加器和组合器调用的结果的部分累加结果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));

将一个Stream转换成一个容器(Map)至少需要考虑以下几点:

  • 目标容器:是List还是Set,或者是Map
  • 新元素如何添加到容器中:是List.add()还是Map.put()
  • 如果并行的进行规约,还需要告诉collect()多个部分结果如何合并成一个

collect()方法定义刚好为:

 R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)

三个参数依次对应上述三条分析。不过每次调用collect()都要传入这三个参数太麻烦,收集器Collector就是对这三个参数的简单封装,所以collect()的另一定义为:

 R collect(Collector collector)
Collectors

java.util.stream.Collectors工具类可通过静态方法生成各种常用的Collector。Collectors类为我们提供了丰富的对流的操作:

1、averagingDouble(ToDoubleFunction
关注
打赏
1665409997
查看更多评论
立即登录/注册

微信扫码登录

0.1026s