前言
实际工作中,我们面临的数据处理场景异常复杂,往往需要多种API组合使用。对于常见的处理需求,Java8提供了例如 Collectors
来协助我们处理集合,比如我们需要将流收集成一个ArrayList
的时候,我们可以直接使用java.util.stream.Collectors#toList
,如下
1 | List collect = students.stream().collect(Collectors.toList()); |
但是 Collectors#toList
的实现相较于上面的函数式编程API,显得不那么简单明了,反而有些复杂:
1 | public static <T> Collector<T, ?, List<T>> toList() { |
对于源码这里就不过多介绍,本次主要是记录工作中一些常见的数据处理场景中,一起看看Stream
是如何体现其优势的。
Stream in action
自定义分组
自定义分组(Map)的key & value
1 | // 根据学生编号分组,value为学生的姓名 |
自定义去重
利用Set去重
1 | @Test |
上述是将 List
转换成 Set
,从而利用 Set
的特性来完成去重,如果想收集的对象是 List
,可以参考下面代码:
1 | List<Student> collect = students.stream().collect(Collectors.collectingAndThen( |
List 转换 Map
工作中我们经常遇到根据ID
或者其他一些标识符将List
转成Map
的场景,对象的一个属性作为key,用来避免例如嵌套for循环。利用 Collectors#groupingBy
可以达到分组的效果,但是获取到的是 Map<K, List<V>>
,不方便我们使用,尽管有时候我们是根据主键(唯一)来分组,对于这样的key,只会存在一个value与之对应。那么我们如何获取到 Map<K, V>
呢,我们可以使用 Collectors#toMap
,JDK1.8中 toMap
有三个重载方法,
1、如果能保证一个key只会对应一个value
1 | Map<String, String> collect = STUDENTS.stream() |
2、如果一个key可能对应多个value(只保留其中一个value)
1 | Map<String, String> collect = STUDENTS.stream().collect(Collectors.toMap( |
3、如果一个key可能对应多个value(只保留其中一个value),但是想以非HashMap
来作为容器
1 | Map<String, String> collect = STUDENTS.stream().collect(Collectors.toMap( |