面试官问我:多个 List 如何取交集、并集、去重并集、差集?
为什么要写在文章最前面
因为如果 List 里面装的是对象,一定要重写 equals 和 hashcode 方法(都是 Object 类下面的方法); 不然比较的是堆内存地址,那么本文也就毫无意义了。
正文开始了
一般情况下,Java操作 List 取交、并集可以采用 apache.commons 包下的 ListUtils 的 removeAll、retainAll 等操作,不过这也破坏了原始的 List对象,如果采用 Java8新特性 Stream 流及 lambda 表达式流操作则可以不影响原始 List 对象而得到两个 List 对象的 交、并、差集。 源代码如下:
可以看到这里返回的都是一个新创建的 List。
Stream 流操作对象类型的集合
/**
* 对象类型的处理
*/
public static void test1() {
List<Student> list1 = new ArrayList<>();
list1.add(new Student("思乡渔夫","F0002"));
list1.add(new Student("阿胖山","F0001"));
list1.add(new Student("牛叔","N1003"));
List<Student> list2 = new ArrayList<>();
list2.add(new Student("牛叔","N1003"));
list2.add(new Student("玉田","N1004"));
// 交集
List<Student> intersection = list1.stream().filter(list2::contains).collect(Collectors.toList());
System.out.println("---交集---"+intersection);
// 差集 (list1 - list2)
List<Student> reduce1 = list1.stream().filter(item -> !list2.contains(item)).collect(Collectors.toList());
System.out.println("---差集 (list1 - list2)---"+reduce1);
// 差集 (list2 - list1)
List<Student> reduce2 = list2.stream().filter(item -> !list1.contains(item)).collect(Collectors.toList());
System.out.println("---差集 (list2 - list1)---"+reduce2);
// 并集
CollectionUtils.addAll(list1,list2);
System.out.println("---并集 list---"+list1);
// 去重并集,方法有很多这里只列举一种
HashSet<Student> hashSet = new HashSet<>(list1);
System.out.println("---去重并集 list---"+hashSet);
}
Stream 流操作字符串类型
/**
* 字符串类型处理
*/
public static void test2(){
List<String> dC = new ArrayList<>();
dC.add("蝙蝠侠");
dC.add("闪电侠");
dC.add("神奇女侠");
List<String> marvel = new ArrayList<>();
marvel.add("钢铁侠");
// 我就要这样放
marvel.add("闪电侠");
marvel.add("洛基(北欧神话中其实是宙斯的弟弟)");
// 交集
List<String> intersection = dC.stream().filter(marvel::contains).collect(Collectors.toList());
System.out.println("---交集---"+intersection);
// 差集 (list1 - list2)
List<String> reduce1 = dC.stream().filter(item -> !marvel.contains(item)).collect(Collectors.toList());
System.out.println("---差集 (dC - marvel)---"+reduce1);
// 差集 (list2 - list1)
List<String> reduce2 = marvel.stream().filter(item -> !dC.contains(item)).collect(Collectors.toList());
System.out.println("---差集 (marvel - dC)---"+reduce2);
// 并集
CollectionUtils.addAll(dC,marvel);
System.out.println("---并集---"+dC);
// 去重并集,方法有很多这里只列举一种
HashSet<String> hashSet = new HashSet<>(dC);
System.out.println("---去重并集---"+hashSet);
}
结尾
北欧神话中,巨狼芬里尔也就是漫威电影宇宙中的雷神三部曲第三部诸神黄昏影片里彩虹桥上的大狗、尘世巨蟒耶梦加得大虫子、死亡女神海拉小姐姐都是洛基的孩子。
欢迎关注我,一个每天忙忙碌碌而今却依然一无所有的小镇青年~~~
- END -