记录下 Java Stream 的一些高效操作
我们日常在代码里处理一些集合逻辑的时候用到 Stream 其实还挺多的,普通的取值过滤集合一般都是结合 ide 的提示就能搞定了,但是有些不太常用的就在这记录下,争取后面都更新记录下来。
自定义 distinctByKey 对结果进行去重
stream 中自带的 distinct 只能对元素进行去重
比如下面代码
public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(1); list.add(2); list = list.stream().distinct().collect(Collectors.toList()); System.out.println(list); }
结果就是去了重的
[1, 2]
但是当我的元素是个复杂对象,我想根据对象里的某个元素进行过滤的时候,就需要用到自定义的 distinctByKey
了,比如下面的想对 userId 进行去重
public static void main(String[] args) { List<StudentRecord> list = new ArrayList<>(); StudentRecord s1 = new StudentRecord(); s1.setUserId(11L); s1.setCourseId(100L); s1.setScore(100); list.add(s1); StudentRecord s2 = new StudentRecord(); s2.setUserId(11L); s2.setCourseId(101L); s2.setScore(100); list.add(s2); StudentRecord s3 = new StudentRecord(); s3.setUserId(12L); s3.setCourseId(100L); s3.setScore(100); list.add(s3); System.out.println(list.stream().distinct().collect(Collectors.toList())); } @Data static class StudentRecord { Long id; Long userId; Long courseId; Integer score; }
结果就是
[StudentRecord(id=null, userId=11, courseId=100, score=100), StudentRecord(id=null, userId=11, courseId=101, score=100), StudentRecord(id=null, userId=12, courseId=100, score=100)]
因为对象都不一样,所以就没法去重了,这里就需要用
public static <T> Predicate<T> distinctByKey( Function<? super T, ?> keyExtractor) { Map<Object, Boolean> seen = new ConcurrentHashMap<>(); return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; }
然后就可以用它来去重了
System.out.println(list.stream().filter(distinctByKey(StudentRecord::getUserId)).collect(Collectors.toList()));
看下结果
[StudentRecord(id=null, userId=11, courseId=100, score=100), StudentRecord(id=null, userId=12, courseId=100, score=100)]
但是说实在的这个功能感觉应该是 stream 默认给实现的
使用 java.util.stream.Collectors#groupingBy 对 list 进行分组
这个使用场景还是蛮多的,上面的场景里比如我要对 userId 进行分组,就一行代码就解决了
System.out.println(list.stream().collect(Collectors.groupingBy(StudentRecord::getUserId)));
结果
{11=[StudentRecord(id=null, userId=11, courseId=100, score=100), StudentRecord(id=null, userId=11, courseId=101, score=100)], 12=[StudentRecord(id=null, userId=12, courseId=100, score=100)]}
很方便的变成了以 userId
作为 key
,以相同 userId
的 StudentRecord
的 List
作为 value
的 map
结构
「其他文章」
- 记录下 Java Stream 的一些高效操作
- Leetcode 1115 交替打印 FooBar ( Print FooBar Alternately *Medium* ) 题解分析
- nginx 日志小记
- Dubbo 使用的几个记忆点
- Leetcode 4 寻找两个正序数组的中位数 ( Median of Two Sorted Arrays *Hard* ) 题解分析
- Leetcode 83 删除排序链表中的重复元素 ( Remove Duplicates from Sorted List *Easy* ) 题解分析
- Disruptor 系列二
- 分享记录一下一个 git 操作方法
- 搬运两个 StackOverflow 上的 Mysql 编码相关的问题解答
- 聊聊 Sharding-Jdbc 分库分表下的分页方案
- 聊聊 Sharding-Jdbc 的简单原理初篇
- 聊聊 Sharding-Jdbc 的简单使用
- Leetcode 028 实现 strStr() ( Implement strStr() ) 题解分析
- Leetcode 021 合并两个有序链表 ( Merge Two Sorted Lists ) 题解分析
- 聊一下 SpringBoot 中动态切换数据源的方法
- redis淘汰策略复习
- redis过期策略复习
- 聊聊 Java 中绕不开的 Synchronized 关键字-二
- 聊聊 Java 中绕不开的 Synchronized 关键字
- 聊聊传说中的 ThreadLocal