讲透JAVA Stream的collect用法与原理,远比你想象的更强大

Posted 架构悟道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了讲透JAVA Stream的collect用法与原理,远比你想象的更强大相关的知识,希望对你有一定的参考价值。

大家好,又见面了。

在我前面的文章《​​吃透JAVA的Stream流操作,多年实践总结​​》中呢,对Stream的整体情况进行了细致全面的讲解,也大概介绍了下结果收集器​​Collectors​​的常见用法 —— 但远不是全部。

本篇文章就来专门剖析collect操作,一起解锁更多高级玩法,让Stream操作真正的成为我们编码中的神兵利器

讲透JAVA

初识Collector

先看一个简单的场景:

现有集团内所有人员列表,需要从中筛选出上海子公司的全部人员

假定人员信息数据如下:

姓名

子公司

部门

年龄

工资

大壮

上海公司

研发一部

28

3000

二牛

上海公司

研发一部

24

2000

铁柱

上海公司

研发二部

34

5000

翠花

南京公司

测试一部

27

3000

玲玲

南京公司

测试二部

31

4000

如果你曾经用过Stream流,或者你看过我前面关于Stream用法介绍的文章,那么借助Stream可以很轻松的实现上述诉求:

public void filterEmployeesByCompany() 
List<Employee> employees = getAllEmployees().stream()
.filter(employee -> "上海公司".equals(employee.getSubCompany()))
.collect(Collectors.toList());
System.out.println(employees);

上述代码中,先创建流,然后通过一系列中间流操作(​​filter​​方法)进行业务层面的处理,然后经由终止操作(​​collect​​方法)将处理后的结果输出为List对象。

讲透JAVA

讲透JAVA

但我们实际面对的需求场景中,往往会有一些更复杂的诉求,比如说:

现有集团内所有人员列表,需要从中筛选出上海子公司的全部人员,并按照部门进行分组

其实也就是加了个新的分组诉求,那就是先按照前面的代码实现逻辑基础上,再对结果进行分组处理就好咯:

public void filterEmployeesThenGroup() 
// 先 筛选
List<Employee> employees = getAllEmployees().stream()
.filter(employee -> "上海公司".equals(employee.getSubCompany()))
.collect(Collectors.toList());
// 再 分组
Map<String, List<Employee>> resultMap = new HashMap<>();
for (Employee employee : employees)
List<Employee> groupList = resultMap
.computeIfAbsent(employee.getDepartment(), k -> new ArrayList<>());
groupList.add(employee);

System.out.println(resultMap);

似乎也没啥毛病,相信很多同学实际编码中也是这么处理的。但其实我们也可以使用Stream操作直接完成:

public void filterEmployeesThenGroupByStream() 
Map<String, List<Employee>> resultMap = getAllEmployees().stream()
.filter(employee -> "上海公司".equals(employee.getSubCompany()))
.collect(Collectors.groupingBy(Employee::getDepartment));
System.out.println(resultMap);

两种写法都可以得到相同的结果:


研发二部=[Employee(subCompany=上海公司, department=研发二部, name=铁柱, age=34, salary=5000)],
研发一部=[Employee(subCompany=上海公司, department=研发一部, name=大壮, age=28, salary=3000),
Employee(subCompany=上海公司, department=研发一部, name=二牛, age=24, salary=2000)]

上述2种写法相比而言,第二种是不是代码上要简洁很多?而且是不是有种自注释的味道了?

通过collect方法的合理恰当利用,可以让Stream适应更多实际的使用场景,大大的提升我们的开发编码效率。下面就一起来全面认识下collect、解锁更多高级操作吧。

讲透JAVA

collect\\Collector\\Collectors区别与关联

刚接触Stream收集器的时候,很多同学都会被​​collect​​,​​Collector​​,​​Collectors​​这几个概念搞的晕头转向,甚至还有很多人即使已经使用Stream好多年,也只是知道collect里面需要传入类似​​Collectors.toList()​​这种简单的用法,对其背后的细节也不甚了解。

这里以一个collect收集器最简单的使用场景来剖析说明下其中的关系:

讲透JAVA

以上是关于讲透JAVA Stream的collect用法与原理,远比你想象的更强大的主要内容,如果未能解决你的问题,请参考以下文章

通俗易懂,java8 .stream().map().collect()用法

通俗易懂,java8 .stream().map().collect()用法

通俗易懂,java8 .stream().map().collect()用法

java基础(15)----stream().map().collect()用法(转)

java8 stream().map().collect()用法

java8 .stream().sorted().filter().map().collect()用法