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]