Collector预定义方法


预定义收集器
1.获取流中元素个数


2.查找流中的最大值和最小值
Collectors.maxBy() Collectors.minBy()

Collectors.summingInt Collectors.summingLong Collectors.summingDouble
它可接受一个把对象映射为求和所需int的函数,并返回一个收集器;该收集器在传递给普通的collect方法后即执行我们需要的汇总操作。


计算数值平均数:Collectors.averagingInt
一次性获取总和、最大值、最小值、平均值。
连接字符串
joining


计算元素个数

上一篇中,reduce方法在把两个值结合起来生成一个新值,它是一个不可变的归约。collect方法的设计就是要改变容器,从而累计要输出的结果。




分组
Collectors.groupingBy根据一个或多个属性对集合中的项目进行分组。


如果你有更特殊的需求,你可以自己实现。

多级分组
User user1 = new User("zhangsan", "beijing", 10);
User user2 = new User("zhangsan", "beijing", 20);
User user3 = new User("lisi", "shanghai", 30);
List<User> list = new ArrayList<User>();
list.add(user1);
list.add(user2);
list.add(user3);
Map<String, Map<String, List<User>>> collect
= list.stream().collect(
Collectors.groupingBy(
User::getAddress, Collectors.groupingBy(User::getName)
)
);
System.out.println(collect);
Collectors.groupingBy工厂方法创 建的收集器,它除了 通的分类函数之外,还可以接受collector类型的第二个参数。那么要进行二级分组的话,我们可以把一个内层groupingBy传递给外层groupingBy.

统计每类菜的元素个数

查找菜单热量最高的菜

把收集器结果转成另一种类型Collectors.collectingAndThen


与groupingBy联合使用的其他收集器的例子
对每组dish进行求和

对流中元素进行改变再收集起来

分区
分区是分组的特殊情况:由一个谓词(返回一个布尔值的函数)作为分类函数,它称分区函数。



groupingBy和 partitioningBy太相似了。


了解Collector接口

supplier方法:用于创建一个空的累加器,供数据收集使用。
supplier可以返回一个空的List

accumulator方法:用于返回执行归约的函数。入参有两个,1个用于累加器(已经收集了n-1个元素),另一个是第n个元素本身。

finisher方法:返回累计过程的最后要调用的一个函数,以便将累加器对象转换为集合操作的最终结果。
如果累加器的类型就是我们想要的类型,那么函数实现可以是这样。

顺序归约的逻辑步骤:

conbiner方法:返回一个供归约操作使用的函数。它定义了对流的各个子部分并行处理时,各个子部分归约所得的加器要如何合并。对于toList而言,这个方法的实现非常简单,只要把从流的第二个部分收集到的项目列表加到遍历第一部分时得到的列表后面就行了。
这个方法可以对流进行并行归约,它用到了fork、join框架和Spliterator抽象。

过程如下:
1.原始流会以递归方式拆分为子流,直到定义流是否需要进一步拆分的某一个条件为非。(并行数小于核数,任务数太小也不好)
2.每个子流都能并行处理。
3.最后使用收集器combiner方法返回函数,将所有结果两两合并。这时会把原始流每次拆分时得到的子流对应的结果合并起来。
//伪代码
function(任务) {
if(足够小) {
return;
}
//拆分为AB
function
}

characteristics方法:它定义了收集器的行为——尤其是关于流是否可以并行归约,以及可以使用哪些优化的提示。characteristics包含三个枚举。

characteristics 方法,返回的是一个 Set 集合,负责 Collector 执行效率的优化,具体要根据是否使用了 parallelStream 以及数据是否有顺序,最终不会影响执行结果。

自己实现一个Collector接口

collect是一个终端操作,它接受的参数是将流中元素累积到汇总结果的各种方式(称为收集器)。
预定义收集器包括将流元素归约和汇总到一个值,例如计算最小值、最大值或平均值。
预定义收集器可以用groupingBy对流中元素进行分组,或用partitioningBy进行分区(分区就是一个map 键只有true和false)。
收集器可以高效地复合起来,进行多级分组、分区和 归约。
我们可以实现Collector接口中定义的方法来开发你自己的收集器。(1.生成累加器容器 2.实现累加器加入元素逻辑 3.实现)
314

被折叠的 条评论
为什么被折叠?



