Java Stream 比较两个 List 的差异,并取出不同的对象
👉 这是一个或许对你有用的社群
🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料:
《项目实战(视频)》:从书中学,往事上“练” 《互联网高频面试题》:面朝简历学习,春暖花开 《架构 x 系统设计》:摧枯拉朽,掌控面试高频场景题 《精进 Java 学习指南》:系统学习,互联网主流技术栈 《必读 Java 源码专栏》:知其然,知其所以然
👉这是一个或许对你有用的开源项目
国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。
功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号等等功能:
Boot 地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro Cloud 地址:https://gitee.com/zhijiantianya/yudao-cloud 视频教程:https://doc.iocoder.cn
可以使用Java8的Stream API来比较两个List的差异,并取出不同的对象。
方式一具体步骤如下:
将两个List转换为Stream类型; 调用Stream的filter方法,将不同的对象过滤出来; 将过滤出的不同的对象转换为List类型。
List<String> list1 = Arrays.asList("A", "B", "C", "D");
List<String> list2 = Arrays.asList("B", "C", "E", "F", "A", "D");
List<String> diff = list1.stream().filter(item -> !list2.contains(item)).collect(Collectors.toList());
List<String> diff1 = list2.stream().filter(item -> !list1.contains(item)).collect(Collectors.toList());
diff.addAll(diff1);
diff.forEach(x -> System.out.println(x));
上述代码中,将两个List类型的对象list1和list2转换为Stream类型,并调用filter方法筛选出不同的对象。最后通过collect方法将不同的对象转换为List类型,并输出结果。
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/ruoyi-vue-pro 视频教程:https://doc.iocoder.cn/video/
方式二具体步骤如下:
List<String> list1 = Arrays.asList("apple", "banana", "orange", "pear");
List<String> list2 = Arrays.asList("apple", "banana", "grape");
List<String> list3 = Stream.concat(
list1.stream().filter(str -> !list2.contains(str)),
list2.stream().filter(str -> !list1.contains(str)))
.collect(Collectors.toList());
System.out.println("Different strings: " + list3);
上述代码,首先定义了两个List<String>
类型的变量list1和list2,分别表示要比较的两个列表。然后使用Stream的concat()
方法将两个Stream对象连接起来,得到一个由两个列表的不同元素组成的Stream。
具体来说,第一个Stream对象是list1中与list2不同的元素,使用filter()
方法过滤出来;第二个Stream对象是list2中与list1不同的元素,同样也是使用filter()方法过滤出来。最后使用collect(Collectors.toList())
将这些不同的元素收集到一个List中,返回的就是两个列表不同的元素组成的集合list3。
最后在控制台输出集合list3,即可得到list1和list2中不同的字符串。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/yudao-cloud 视频教程:https://doc.iocoder.cn/video/
方式三具体步骤如下:
List<Object> l1 = new ArrayList<>();
l1.add(new Object(1, "a"));
l1.add(new Object(2, "b"));
l1.add(new Object(3, "c"));
List<Object> l2 = new ArrayList<>();
l2.add(new Object(1, "a"));
l2.add(new Object(3, "c"));
l2.add(new Object(4, "d"));
List<Object> resultList = Stream.concat(l1.stream(), l2.stream())
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.filter(e -> e.getValue() == 1)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
首先将两个List通过Stream.concat
方法合并成一个新的Stream对象,并使用Collectors.groupingBy
方法来按照对象值进行分组计数。然后通过过滤出现次数为1的对象,即为两个List中不同的对象。最后用Collectors.toList
方法将所有不同的对象放到一个新的List中。
需要注意的是,Object类需要正确实现equals和hashCode方法,以便Stream能够正确进行对象的比较。同时,此方法适用于List中存放的对象是Java内置类型或者自定义类型,但不适用于包含数组、Map等集合类型的情况。
方式四具体步骤如下:
根据对象的属性进行比较两个拥有相同对象List的集合,并取出不同对象。
List<ProductAttributeNameDTO> l1 = Arrays.asList(
new ProductAttributeNameDTO(1L, "颜色"),
new ProductAttributeNameDTO(2L, "尺码"),
new ProductAttributeNameDTO(3L, "重量")
);
List<ProductAttributeNameDTO> l2 = Arrays.asList(
new ProductAttributeNameDTO(1L, "颜色"),
new ProductAttributeNameDTO(3L, "重量"),
new ProductAttributeNameDTO(4L, "材质")
);
List<ProductAttributeNameDTO> resultList = Stream.concat(l1.stream(), l2.stream())
.collect(Collectors.groupingBy(ProductAttributeNameDTO::getName, Collectors.counting()))
.entrySet().stream()
.filter(e -> e.getValue() == 1)
.map(e -> e.getKey())
.map(name -> Stream.concat(l1.stream(), l2.stream()).filter(p -> p.getName().equals(name)).findFirst().get())
.collect(Collectors.toList());
首先将两个List通过Stream.concat
方法合并成一个新的Stream对象,并使用Collectors.groupingBy
方法来按照属性名称进行分组计数。然后通过过滤出现次数为1的属性名称,即为两个List中不同的属性名称。最后使用Stream.map
方法获取对应名称的第一个ProductAttributeNameDTO
对象,放到一个新的List中。
需要注意的是,ProductAttributeNameDTO
类需要正确实现equals和hashCode方法,以便Stream能够正确进行对象的比较。同时,此方法适用于List中存放的是ProductAttributeNameDTO
类型的对象。如果存放其他类型的对象,则需要根据对象的属性进行比较或自定义Comparator进行比较。
欢迎加入我的知识星球,全面提升技术能力。
👉 加入方式,“长按”或“扫描”下方二维码噢:
星球的内容包括:项目实战、面试招聘、源码解析、学习路线。
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
微信扫码关注该文公众号作者