6.1 收集器简介
6.1.1 收集器用作高级归约
对流调用collect方法将对流 中的元素触发一个归约操作(由Collector来参数化)。
一般来说,Collector会对元素应用一个转换函数(很多时候是不体现任何效果的恒等转换,例如 toList),并将结果累积在一个数据结构中,从而产生这一过程的最终输出。
6.1.2 预定义收集器
6.2 归约和汇总
在需要将流项目重组成集合时,一般会使用收集器(Stream方法collect的参 数)。再宽泛一点来说,但凡要把流中所有的项目合并成一个结果时就可以用。这个结果可以是任何类 型,可以复杂如代表一棵树的多级映射,或是简单如一个整数。
6.2.1 查找流中的最大值和最小值
Optional<Dish> max = menu.stream().collect(maxBy(Comparator.comparingInt(Dish::getCalories)));
Optional<Dish> min = menu.stream().min(Comparator.comparingInt(Dish::getCalories));
6.2.2 汇总
Collectors类专门为汇总提供了一个工厂方法:Collectors.summingInt。它可接受一个把对象映 射为求和所需int的函数,并返回一个收集器;该收集器在传递给普通的collect方法后即执行我们需要 的汇总操作。
Integer result1 = menu.stream().collect(summingInt(Dish::getCalories));
Integer result2 = menu.stream().mapToInt(Dish::getCalories).sum();
6.2.3 连接字符串
String str = menu.stream().map(Dish::getName).collect(joining(","));
6.2.4 广义的归约汇总
事实上,我们已经讨论的所有收集器,都是一个可以用reducing工厂方法定义的归约过程的特殊情况而 已。Collectors.reducing工厂方法是所有这些特殊情况的一般化。可以说,先前讨论的案例仅仅是 为了方便程序员而已。
reduce方法旨在把两个 值结合起来生成一个新值,它是一个不可变的归约。
与此相反,collect方法的设计就是要改变容器,从而累积要输出的结果。
6.3 分组
Map<Boolean, List<Dish>> map = menu.stream().collect(groupingBy(Dish::isVegetarian));
6.3.1 多级分组
Map<Dish.Type, Map<String, List<Dish>>> map = menu.stream().collect(groupingBy(Dish::getType, groupingBy(dish -> {
if (dish.getCalories() >= 700) {
return "FAT";
} else if (dish.getCalories() >= 400 && dish.getCalories() < 700) {
return "NORMAL";
} else {
return "DICT";
}
})));
6.3.2 按子组收集数据
// 要数一数菜单中每类菜有多少个
Map<Dish.Type, Long> map = menu.stream().collect(groupingBy(Dish::getType, counting()));
// 查找菜单中热量最高的菜肴的收集器改一改,按照菜的类型分类
Map<Dish.Type, Optional<Dish>> collect = menu.stream().collect(groupingBy(Dish::getType,maxBy(Comparator.comparing(Dish::getCalories))));
// 在上一步的基础上去掉Optional
Map<Dish.Type, Dish> collect1 = menu.stream().collect(groupingBy(Dish::getType,collectingAndThen(maxBy(Comparator.comparing(Dish::getCalories)), Optional::get)));
6.4 分区
Map<Boolean, List<Dish>> map = menu.stream().collect(partitioningBy(Dish::isVegetarian));
List<Dish> dishes = map.get(true);
6.4.1 分区的优势
分区的好处在于保留了分区函数返回true或false的两套流元素列表。
6.5 收集器接口
6.6 开发你自己的收集器以获得更好的性能
6.7 小结
以下是你应从本章中学到的关键概念。
collect是一个终端操作,它接受的参数是将流中元素累积到汇总结果的各种方式(称为收集器)。
预定义收集器包括将流元素归约和汇总到一个值,例如计算最小值、最大值或平均值。
这些收集器总 结在表6-1中。 预定义收集器可以用groupingBy对流中元素进行分组,或用partitioningBy进行分区。
收集器可以高效地复合起来,进行多级分组、分区和归约。
你可以实现Collector接口中定义的方法来开发你自己的收集器。
6.5和6.6的内容看的有些晕乎,先跳过