系统学习Java新特性-用流收集数据

阅读《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
2
3
4
5
6
7
8
9
java复制代码    //求最值收集器使用示例
//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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
java复制代码    //# 汇总收集器示例
//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()方法得到的所有字符串连接成一个字符串。

1
2
3
4
5
6
7
java复制代码    //# 连接收集器
String shortNames =
Dish.menu.stream()
.map(Dish::getName)
.collect(Collectors.joining(", "));
// pork, beef, chicken, french fries,...
System.out.println(shortNames);

2.4 广义的归约汇总

前三种收集器,本质是reducing的常见特殊情况处理。比如,求和,本质内容是如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
java复制代码    //#广义的归约汇总
//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后面内容阅读梳理~

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%