阅读《Java实战》,本文为第6章总结,主要介绍收集器(Collectors)的使用,如收集器简介、归约与汇总处理、分组分区、收集器接口机制、自定义一个高效的收集器。
1、收集器(Collectors)
collect(Collector<? super T, A, R> collector)是一个终端操作,接受的参数是定义流中元素累积到汇总结果的各种方式,该参数即为收集器。收集器包含的功能主要有两个:
- 用作高级归约:对流中的元素触发以一个归约操作,如
Collectors.toList()将结构收集到一个List中返回。 - 预定义收集器:利用Collectors类提供的工厂方法(如
groupingBy)创建收集器,扩展相关功能,主要三大功能如下:- 将流元素归约和汇总为一个值
- 元素分组
- 元素分区
2、归约和汇总
2.1 查询流中的最大值和最小值
Collectors.maxBy(Comparator<? super T> comparator):最大值收集器Collectors.minBy(Comparator<? super T> comparator):最小值收集器
//求最值收集器使用示例
//1.定义比较器Comparator
Comparator<Dish> dishCaloriesComparable =
Comparator.comparingInt(Dish::getCalories);
//2.使用maxBy求出最大热量的菜肴
Optional<Dish> mostCaloriesDish =
Dish.menu.stream()
.collect(Collectors.maxBy(dishCaloriesComparable));
mostCaloriesDish.ifPresent(System.out::println);// pork
2.2 汇总
主要对结果做汇总统计,比如求和、平均值以及统计,具体使用如下:
//# 汇总收集器示例
//1、求和
int totalCalories =
Dish.menu.stream()
.collect(Collectors.summingInt(Dish::getCalories));
System.out.println(totalCalories);//4300
//2、求平均
double avgCalories =
Dish.menu.stream()
.collect(Collectors.averagingInt(Dish::getCalories));
System.out.println(avgCalories);//477.77777777
//3、统计
IntSummaryStatistics menuStatistics =
Dish.menu.stream()
.collect(Collectors.summarizingInt(Dish::getCalories));
//IntSummaryStatistics{count=9, sum=4300, min=120, average=477.777778, max=800}
System.out.println(menuStatistics);
2.3 连接字符串
joining工厂方法返回的收集器会把流中每一个对象引用toString()方法得到的所有字符串连接成一个字符串。
//# 连接收集器
String shortNames =
Dish.menu.stream()
.map(Dish::getName)
.collect(Collectors.joining(", "));
// pork, beef, chicken, french fries,...
System.out.println(shortNames);
2.4 广义的归约汇总
前三种收集器,本质是reducing的常见特殊情况处理。比如,求和,本质内容是如下:
//#广义的归约汇总
//1、求和
int totalCalories1 =
Dish.menu.stream()
.collect(Collectors.reducing(0,Dish::getCalories,(i,j) -> i+j));
System.out.println(totalCalories1);
//2、求最值
Optional<Dish> mostCaloriesDish1 =
Dish.menu.stream()
.collect(Collectors.reducing((d1,d2) -> d1.getCalories()>d2.getCalories()?d1:d2));
//3、joining字符串拼接
String shortNames1 =
Dish.menu.stream()
.collect(Collectors.reducing("",Dish::getName,(s1,s2) -> s1+","+s2));
System.out.println(shortNames1);
3、分组
与数据库的常见操作,根据一个或者多个属性对集合中的项目进行分组类似。Collectors.groupingBy工厂方法返回的收集器可以实现该功能。
待完成:
2021年11月7日 新工作岗位入职,因为岗位需要nestjs相关技术栈+源码阅读活动,暂时暂缓javaCore后面内容阅读梳理~