Java8 stream 处理 List 交集、差集、去重
Java8的新特性——Stream常用于处理集合,它不会改变集合原有的结构,优点是Stream的代码会比用for循环处理更加的简洁。
1:二个集合的交集
例如:找出两个班名字相同的学生
@Data public class User { /** * 工号 */ private String userNo; /** * 姓名 */ private String userName; public User(String userNo, String userName) { this.userNo = userNo; this.userName = userName; } /** * 对象的比较涉及到equals()的重写, 这里仅仅比较studentName是否相同 */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof User)) { return false; } User user = (User) o; return userName.equals(user.getUserName()); } }
交集方法:
/** * 取交集方法 */ public static void test1() { // 一班的学生 List<User> class01 = new ArrayList<>(); class01.add(new User("1", "小明")); class01.add(new User("2", "小黑")); class01.add(new User("3", "大白")); // 二班的学生 List<User> class02 = new ArrayList<>(); class02.add(new User("1", "小黑")); class02.add(new User("2", "大白")); // 找两个班名字相同的同学(取交集),比较用的是重写的equals() List<User> sameName = class01.stream().filter(class02::contains).collect(Collectors.toList()); // 取出交集学生名称 List<String> userNameList = sameName.stream().map(User::getUserName).collect(Collectors.toList()); System.out.println("交集学生姓名:" + userNameList); }
输出结果:
交集学生姓名:[小黑, 大白]
需要注意的是:
-
class01.stream().filter(class02::contains)
的filter()
会 保留 符合表达式的结果,这里面表达式的内容是 2班和1班名字相同的同学 -
forEach是遍历集合,代替了for循环,代码更为简洁
-
collect(Collectors.toList())
、collect(Collectors.toSet())
、collect(Collectors.toMap())
将Stream的数据归集到List、Map、Set等集合
2:二个集合差集
/** * 取差集 */ public static void test2() { List<String> list01 = Arrays.asList("a", "b", "c", "d", "e", "f", "g"); List<String> list02 = Arrays.asList("a", "c", "f", "d"); // list01和list02的差集, 仅保留了 b,c List<String> result = list01.stream().filter(word -> !list02.contains(word)).collect(Collectors.toList()); System.out.println("差集结果:" + result); }
输出结果:
差集结果:[b, e, g]
表达式 list01.stream().filter(word-> ! list02.contains(word))
,要找的元素,它的特征是只存在list01中,但不存在list02中,! list02.contains(word)
就是说这个元素不在list02中。
3:集合取重
/** * 去重 */ public static void test3() { List<String> list = Arrays.asList("a", "b", "c", "a", "d", "b"); System.out.println("去重前:" + list); List<String> result = list.stream().distinct().collect(Collectors.toList()); System.out.print("去重后:" + result); }
输出结果:
去重后结果:[a, b, c, d]
4:list.stream()构造方法
list.stream()
它是个Stream的构造方法,Stream的构造方法如下:
4.1 用集合创建Stream
List<String> list=Arrays.asList("a","b","c"); //创建顺序流 Stream<String> stream=list.stream(); //创建并行流 Stream<String> parallelStream=list.parallelStream();
4.2 用数组Arrays.stream(array)
创建Stream
int[] array={1,2,3,4,5}; IntStream stream=Arrays.stream(array);
4.3 用Stream<T> of(T... values)
创建Stream
Stream<Integer> stream=Stream.of(1,2,3,4,5);
常用的是上面这三种,另外还有iterate()
,generate()
,后者是生成随机数,两个构造方法均产生无限流(即元素的个数是无限的)。
如果要求数量有限,则需要用 limit 来限制,如:
/** * Stream list限制数量 */ public static void test4() { Stream<Integer> result = Stream.iterate(0, num -> num + 2).limit(5); System.out.println(result.collect(Collectors.toList())); }
输出结果:[0, 2, 4, 6, 8]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2019-05-14 自定义注解的实现思路