毫不夸张的讲,如果发现某个功能在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最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?