Java工具类:对比两个集合并返回差异

在实际的软件开发过程中,经常会遇到需要对比两个集合并找出它们之间的差异的情况。为了解决这个问题,我们可以编写一个Java工具类来完成这个任务。本文将介绍如何编写这样一个工具类,并提供详细的代码解释和使用示例。

问题描述

假设我们有两个集合,我们需要对比它们并找出它们之间的差异。我们希望能够找出集合1中存在但集合2中不存在的元素,以及集合2中存在但集合1中不存在的元素。

import java.util.*;public class CollectionComparator {/*** 比较两个集合,返回包含不变、新增和删除元素的Map。** @param list1  第一个集合* @param list2  第二个集合* @param fields 用于判断集合中元素是否一样的字段名* @param <T>    集合中元素的类型* @return 包含不变、新增和删除元素的Map*/public static <T> Map<String, List<T>> compareCollections(List<T> list1, List<T> list2, String... fields) {// 创建结果MapMap<String, List<T>> result = new HashMap<>();// 计算新增、删除和不变的元素,并放入结果Map中result.put("新增", findAddedElements(list1, list2, fields));result.put("删除", findRemovedElements(list1, list2, fields));result.put("不变", findUnchangedElements(list1, list2, fields));return result;}/*** 查找新增的元素** @param list1  第一个集合* @param list2  第二个集合* @param fields 用于判断集合中元素是否一样的字段名* @param <T>    集合中元素的类型* @return 新增的元素列表*/private static <T> List<T> findAddedElements(List<T> list1, List<T> list2, String[] fields) {return findDifference(list2, list1, fields);}/*** 查找删除的元素** @param list1  第一个集合* @param list2  第二个集合* @param fields 用于判断集合中元素是否一样的字段名* @param <T>    集合中元素的类型* @return 删除的元素列表*/private static <T> List<T> findRemovedElements(List<T> list1, List<T> list2, String[] fields) {return findDifference(list1, list2, fields);}/*** 查找不变的元素** @param list1  第一个集合* @param list2  第二个集合* @param fields 用于判断集合中元素是否一样的字段名* @param <T>    集合中元素的类型* @return 不变的元素列表*/private static <T> List<T> findUnchangedElements(List<T> list1, List<T> list2, String[] fields) {// 创建字段集合Set<String> fieldSet = new HashSet<>(Arrays.asList(fields));// 创建不变的元素列表List<T> unchangedElements = new ArrayList<>();// 遍历第一个集合for (T obj1 : list1) {boolean found = false;// 遍历第二个集合for (T obj2 : list2) {// 判断两个对象是否相等if (areEqual(obj1, obj2, fieldSet)) {found = true;break;}}// 如果第一个集合中的元素在第二个集合中存在,则添加到不变的元素列表中if (found) {unchangedElements.add(obj1);}}return unchangedElements;}/*** 查找两个集合的差异** @param list1  第一个集合* @param list2  第二个集合* @param fields 用于判断集合中元素是否一样的字段名* @param <T>    集合中元素的类型* @return 差异元素列表*/private static <T> List<T> findDifference(List<T> list1, List<T> list2, String[] fields) {// 创建字段集合Set<String> fieldSet = new HashSet<>(Arrays.asList(fields));// 创建差异元素列表List<T> differenceList = new ArrayList<>();// 遍历第一个集合for (T obj1 : list1) {boolean found = false;// 遍历第二个集合for (T obj2 : list2) {// 判断两个对象是否相等if (areEqual(obj1, obj2, fieldSet)) {found = true;break;}}// 如果第一个集合中的元素在第二个集合中不存在,则添加到差异元素列表中if (!found) {differenceList.add(obj1);}}return differenceList;}/*** 比较两个对象是否相等** @param obj1   对象1* @param obj2   对象2* @param fields 用于判断对象是否相等的字段集合* @param <T>    对象的类型* @return 如果对象相等则返回true,否则返回false*/private static <T> boolean areEqual(T obj1, T obj2, Set<String> fields) {// 遍历字段集合for (String field : fields) {try {// 获取对象1中字段的值Object value1 = obj1.getClass().getField(field).get(obj1);// 获取对象2中字段的值Object value2 = obj2.getClass().getField(field).get(obj2);// 判断两个字段值是否相等if (!Objects.equals(value1, value2)) {return false;}} catch (NoSuchFieldException | IllegalAccessException e) {// 捕获异常并打印异常信息e.printStackTrace();}}// 如果所有字段值都相等,则返回truereturn true;}public static void main(String[] args) {// 测试示例List<Person> list1 = new ArrayList<>();list1.add(new Person("张三", 10));list1.add(new Person("张三2", 10));list1.add(new Person("张三3", 10));List<Person> list2 = new ArrayList<>();list2.add(new Person("张三", 10));list2.add(new Person("张三2", 10));list2.add(new Person("张三4", 10));Map<String, List<Person>> differenceMap = compareCollections(list1, list2, "name", "age");for (Map.Entry<String, List<Person>> entry : differenceMap.entrySet()) {System.out.println(entry.getKey() + "的元素:");for (Person person : entry.getValue()) {System.out.println(person);}}}static class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}}
}

使用示例

使用示例
main 方法中,我们演示了如何使用该工具类进行集合比较,并输出差异信息。运行程序后,将会输出如下结果:

新增的元素:
Person{name='张三4', age=10}
不变的元素:
Person{name='张三', age=10}
Person{name='张三2', age=10}
删除的元素:
Person{name='张三3', age=10}

总结

本文介绍了如何使用Java编写一个工具类来对比两个集合并找出它们之间的差异。通过编写这样一个工具类,我们可以更轻松地处理集合比较的需求,并更好地理解集合之间的关系。希望本文对您有所帮助,欢迎提出建议和意见。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/806753.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

头歌-机器学习 第12次实验 Adaboost算法

第1关&#xff1a;什么是集成学习 任务描述 本关任务&#xff1a;根据本节课所学知识完成本关所设置的选择题。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.什么是集成学习。 什么是集成学习 集成学习方法是一种常用的机器学习方法&#xff0c;分为b…

Vue2.x实现商城购物车

1.实现购物车页面 在页面中显示购物车中的商品信息&#xff0c;并能进行数量增减及商品删除操作&#xff0c;购物车中金额也随商品数量的变化而变化 2.创建cart.html页面 创建cart.html页面&#xff0c;在其中创建Vue实例&#xff0c;实例中首先准备一些商品信息以供显示&a…

天软特色因子看板 (2024.4 第3期)

该因子看板跟踪天软特色因子A05005(近一月单笔流出金额占比(%)&#xff0c;该因子为近一月单笔流出金额占比(% 均值因子&#xff0c;用以刻画下跌时的 单成交中可能存在的抄底现象 今日为该因子跟踪第3期&#xff0c;跟踪其在SH000852 (中证1000) 中的表现&#xff0c;要点如下…

21、Lua 面向对象

Lua 面向对象 Lua 面向对象面向对象特征Lua 中面向对象一个简单实例创建对象访问属性访问成员函数完整实例 Lua 继承完整实例 函数重写 Lua 面向对象 面向对象编程&#xff08;Object Oriented Programming&#xff0c;OOP&#xff09;是一种非常流行的计算机编程架构。 以下…

使用 IEEE (1735) Verilog 标准机制进行 IP 保护

在跑仿真的时候&#xff0c;如果使用第三方IP&#xff0c;经常会遇到第三方IP中有加密代码&#xff0c;有时又会遇到同样的环境既可以用VCS跑&#xff0c;也可以用XRUN跑&#xff0c;我就好奇第三方IP如何支持两个公司的加解密方式的。 以前只是知道VCS使用protect-endprotect…

【CSS】通过CSS层叠样式插入文字\content中字符串换行操作

某些页面经常需要插入文字去提醒&#xff0c;例如财务税票验证页面&#xff0c;系统老旧又不维护&#xff0c;提交前又不会提醒要税票验证&#xff0c;每次都要返工跑两趟&#xff01;&#xff01; 故&#xff0c;解决办法就是自己添加第三方的CSS样式&#xff0c;插入文字提醒…

微信小程序转盘抽奖

场景&#xff1a; 在微信小程序里面开展抽奖活动使用转盘抽奖&#xff1b;类似下图&#xff08;图片来自百度&#xff09; 方法&#xff1a; 使用lukcy-canvas组件 在 微信小程序 中使用 | 基于 Js / TS / Vue / React / 微信小程序 / uni-app / Taro 的【大转盘 & 九宫…

Dolphinscheduler单机部署

目录 概述实践二进制包前置准备工作解压并启动 Dolphinscheduler登录 Dolphinscheduler启停服务配置数据库 结束 概述 Standalone仅适用于 Dolphinscheduler 的快速体验 实践 官网 官网standalone 二进制包 二进制包&#xff1a;在下载页面下载 Dolphinscheduler 二进制包…

Java中雪花算法的实现

背景 在id生成器中&#xff0c;我们自己手写一个自增的id生成器很简单&#xff0c;也很好用。但这只是单机中的id生成器&#xff0c;当我们在集群中使用时&#xff0c;一个集群就会有一个id生成器实例&#xff0c;就意味着每一个集群的id都会从0开始&#xff0c;最后就会导致i…

IO流【 文件字符输入、出流;带缓冲区的字符输入、出流;对象流】

day36 IO流 字符流继承图 字符流 继day35 应用场景&#xff1a;操作纯文本数据 注意&#xff1a;字符流 字节流编译器 编译器&#xff1a;可以识别中文字符和非中文字符&#xff0c;非中文字符获取1个字节&#xff08;一个字节一个字符&#xff09;&#xff0c;编译器会根据…

深入浅出Golang image库:编写高效的图像处理代码

深入浅出Golang image库&#xff1a;编写高效的图像处理代码 引言image库概览图像处理基础概念image库的主要组成和功能image接口图像格式的支持color模型 结论 图像的基本操作创建图像新图像的创建从文件加载图像 图像的保存与导出图像的颜色和像素处理绘制基本形状和文字 高级…

【开源社区】openEuler、openGauss、openHiTLS、MindSpore

【开源社区】openEuler、openGauss、openHiTLS、MindSpore 写在最前面开源社区参与和贡献的一般方式开源技术的需求和贡献方向 openEuler 社区&#xff1a;开源系统官方网站官方介绍贡献攻略开源技术需求 openGauss 社区&#xff1a;开源数据库官方网站官方介绍贡献攻略开源技术…

数据结构(三)----栈和队列

目录 一.栈 1.栈的基本概念 2.栈的基本操作 3.顺序栈的实现 •顺序栈的定义 •顺序栈的初始化 •进栈操作 •出栈操作 •读栈顶元素操作 •若使用另一种方式: 4.链栈的实现 •链栈的进栈操作 •链栈的出栈操作 •读栈顶元素 二.队列 1.队列的基本概念 2.队列的基…

使用Python实现K均值聚类算法

K均值&#xff08;K-Means&#xff09;算法是一种常用的聚类算法&#xff0c;它将数据集分成K个簇&#xff0c;每个簇的中心点代表该簇的质心&#xff0c;使得每个样本点到所属簇的质心的距离最小化。在本文中&#xff0c;我们将使用Python来实现一个基本的K均值聚类算法&#…

关于ABP 新增表,dbfirst模式

下面的代码是基于abp生成的项目&#xff0c;项目名&#xff1a;Store 1.在Domain结尾的项目中通过EF工具生成数据实体&#xff1a; Scaffold-DbContext Data Source服务器IP;Initial Catalog数据库;User Idsa;Password密码;EncryptFalse; Microsoft.EntityFrameworkCore.SqlS…

JVM常量池

JVM中的常量池主要有以下几个类别&#xff0c;它们各自在JVM中的位置随着JDK版本的演进而有所变化&#xff1a; Class文件常量池&#xff1a; 位置&#xff1a;存在于每个独立的.class文件中。这是编译期间生成的二进制文件的一部分&#xff0c;它包含了该类或接口的所有编译期…

Java基础_15集合及其方法

今天的内容 1.集合 1.集合【重点】 1.1为什么使用集合 集合和数组是一样的都是用来存储数据的&#xff01;&#xff01;&#xff01; 真实的开发的时候&#xff0c;使用的是集合不是数组&#xff0c;为啥&#xff1f; 数组存数据: ​ 1.数组的容量是固定的 ​ 2.数组封装的方法…

慢品人间烟火色,闲观万事岁月长

小女孩的衣柜里&#xff0c;怎能缺少一套别致的新中式穿搭&#xff1f;让我们的小公主在时尚与传统中寻找平衡 演绎属于自己的中国风魅力精致的小立领&#xff0c;淡淡的文艺复古气息 上衣系带设计&#xff0c;外加一层高透轻纱穿上身如亭亭玉立的大小姐整个人仿佛笼罩了一层…

CVP(ChatGPT、Vector Database和Prompt)

CVP实际上指的是ChatGPT、Vector Database和Prompt的结合&#xff0c;这是一种新型的技术栈&#xff0c;用于构建智能应用。 首先&#xff0c;我们来看这三个组成部分&#xff1a; ChatGPT&#xff1a;这是一个强大的语言模型&#xff0c;它能够理解并生成自然语言文本。Chat…

【docker】之linux写shell脚本备份线上数据库(备份为dump文件)

目录 1. SH文件1.1 SH文件示例1.2 文件解释1.3 .sh文件执行 2. 备份线上数据库的.sh文件2.1 文件命令解析 3. 命令执行4. 线下dump文件的恢复与备份 环境&#xff1a;linux容器&#xff1a;docker 1. SH文件 SH文件通常指的是 Shell 脚本文件&#xff0c;文件后缀名为.sh&…