您的位置:首页 > 编程语言 > Java开发

《Java in Action》-1 第6章用流收集数据

2016-10-04 02:38 239 查看

第6章 用流收集数据

6. 1收集器简介

6.1.1 收集器用作高级归约

对流调用collect方法将对流中的元素触发一个归约操作(由Collector来参数化)。

Collectors实用类提供了很多静态工厂方法,可以方便地创建常见收集器的实例,只要拿来用 就可以了。Collectors.toList();

6.1.2 预定义收集器

Collector类提供的工厂方法创建的收集器,有三个功能:

*将流元素归约和汇总为一个值

*元素分组

*元素分区

6.2 归约和汇总

long howManyDished = menu.stream().collect(Collectors.counting());

6.2.1 查找流中的最大值和最小值

可以使用两个收集器,Collectors.maxBy和Collectors.minBy,来计算流中的最大或最小值。

6.2.2 汇总

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

Collectors.averagingInt求平均数。

可以使用Collectors.summarizingInt工厂方法返回的收集器,通过一次summarizing操作就可以数出菜单中元素的个数,并得到菜肴热量总和、平均值、最大值和最小值。

6.2.3 连接字符串

joining工厂方法返回的收集器会把对流中每一个对象应用toString方法得到的所有字符串连接成一个字符串。

6.2.4 广义的归约汇总

Collectors.reducing工厂方法是所有这些特殊情况的一般化。

例子:用reducing方法创建的收集器来计算你菜单的总热量

int totalCalories = menu.stream().collect(reducting(0,Dish :: getCalories,(i,j) -> i + j));

需要三个参数:

1)归约操作的起始值,也是流中更没有元素时的返回值,所以很明显对于数值和而言0是一个合适的值

2)将菜肴转换成一个表示其所含热量的int

3)第三个参数是一个BinaryOperator,将两个项目累积成一个同类型的值。

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

1.收集框架的灵活性:以不同的方法执行同样的操作

2.根据情况选择最佳解决方案

6.3 分组

Map<DIsh.Type,List<Dish>> dishedByType = menu.stream().collect(groupingBy(Dish :: getType));

6.3.1 多级分组

Collectors.groupingBy工厂方法创建的收集器,除了普通的分类函数之外,还可以接受collector类型的第二个参数。

6.3.2 按子组收集数据

Map<Dish.Type,Long> typeCount = menu.stream().collect(

groupingBy(Dish :: getType,counting()));

1.把收集器的结果转换为另一种类型

使用Collectors.collectingAndThen工厂方法把收集器返回的结果转换为另一种类型。

例子:查找每个子组中热量最高的Dish

Map<Dish.Type,Dish> mostCaloricByType = menu.stream().collect(grouping(Dish :: getType,

collectingAndThen(maxBy(comparingInt(Dish :: getCalories)),Optional :: get)));

2.与groupingBy联合使用的其他收集器的例子

6.4 分区

分区是分组的特殊情况:有一个谓词(返回一个布尔值的函数)作为分类函数,它称分区函数。分区函数返回一个布尔值,这意味着得到的分组Map的键类型是Boolean,于是它最多可以分为两组——true是一组,false是一组。

Map<Boolean, List<Dish>> partitionedMenu = menu.stream().collect(partitioningBy(Dish :: isVegetarian));

List<Dish> vegetarianDishes = partitionedMenu.get(true);

6.4.1 分区的优势

分区的好处在于保留了分区函数返回true或false的两套流元素列表。

6.4.2 将数字按质数和非质数分区







6.5 收集器接口

6.6 开发你自己的收集器以获得更好的性能

6.7 小结

*collect是一个中断操作,它接受的参数是将流中元素累积到汇总结果的各种方式(称为收集器)

*预定义收集器包括将流元素归约和汇总到一个值,例如计算最小值、最大值或平均值。

*预定义收集器可以用groupingBy对流中元素进行分组,或用partitioningBy进行分区。

*收集器可以高效地复合起来,进行多级分组、分区和归约。

*你可以实现Collector接口中定义的方法来开发你自己的收集器。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: