Java 比较两个对象的不同之处(old, new) 包含 bean 对象下的 list, Map , bean 的细节
Java 比较两个对象的不同之处(old, new) 包含 bean 对象下的 list, Map , bean 的细节
package com.icil.pinpal.test1; import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.junit.Test;
import org.springframework.util.Assert; import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors; /***************************
*<pre>
* @Project Name : base-case-test-service
* @Package : com.icil.pinpal.test1
* @File Name : BaseTest
* @Author : Sea
* @Mail : lshan523@163.com
* @Date : 2022/11/21 16:43
* @Purpose :
* @History :
*</pre>
***************************/
public class BaseTest { // ########################## 准备bean ##############################
/* @AllArgsConstructor
@NoArgsConstructor
@Data
static public class BaseDO {
private String name;
private Integer age;
private List<String> likes;
private List<Child> childrens;
private Map mymap;
private Child childx; public BaseDO(String name, Integer age, List<String> likes, List<Child> childrens) {
this.name = name;
this.age = age;
this.likes = likes;
this.childrens = childrens;
}
} @AllArgsConstructor
@NoArgsConstructor
@Data
static public class Child {
private String name;
private Integer age;
}*/ // ########################## 比较 方法 ############################## private static final List<Class<?>> WRAPPER = Arrays.asList(Byte.class, Short.class,
Integer.class, Long.class, Float.class, Double.class, Character.class,
Boolean.class, String.class); /**
* compare the bean fields value if different
* @param source obj
* @param target obj
* @return {key:[old,new]}
* @throws Exception
*/
public static JSONObject getDiff(Object source, Object target) throws Exception {
JSONObject diff =new JSONObject();
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
Class<?> compareObj = target.getClass();
Field[] fields = compareObj.getDeclaredFields();
for (Field field : fields) {
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), compareObj);
Method getMethod = pd.getReadMethod();
Object o1 = getMethod.invoke(source);
Object o2 = getMethod.invoke(target);
String s1 = o1 == null ? "" : o1.toString();
String s2 = o2 == null ? "" : o2.toString();
if (!s1.equals(s2))
{
//############### 处理list,对比list 的不同 ##################
if(o1 instanceof Collection){
Collection<Object> o11 = (Collection) o1;
Collection<Object> o22 = (Collection) o2;
Collection common = o11.stream().filter(o -> o22.contains(o)).collect(Collectors.toList());
o11.removeAll(common);
o22.removeAll(common);
diff.put(field.getName(), Arrays.asList(o11,o22));
}
else if(o1 instanceof Map)
{ // ######### 处理 map 对比map 的不同 #########
Map<String,Object> O11 = (Map) o1;
Map<String,Object> O22 = (Map) o2;
// o1 diff 02
JSONObject o1diffo2 = new JSONObject();
for(Map.Entry<String,Object> oo1 : O11.entrySet())
{
String key = oo1.getKey();
O11.getOrDefault(key,"");
if(!O11.getOrDefault(key,"").equals(O22.getOrDefault(key,""))){
o1diffo2.put(key,oo1.getValue());
}
}
// o2 diff 01
JSONObject o2diffo1 = new JSONObject();
for(Map.Entry<String,Object> oo2 : O22.entrySet())
{
String key = oo2.getKey();
O11.getOrDefault(key,"");
if(!O22.getOrDefault(key,"").equals(O11.getOrDefault(key,""))){
o1diffo1.put(key,oo2.getValue());
}
}
diff.put(field.getName(), Arrays.asList(o1diffo2,o2diffo1));
}
// ################## 如果为 bean 对象 (不是基本类型,不是list 也不是map) ##################
else if((!o1.getClass().isPrimitive() && !WRAPPER.contains(o1.getClass())) && !(o1 instanceof Collection) && !(o1 instanceof Map))
{
diff.put(field.getName(), getDiff(o1,o2));
}
else
{
diff.put(field.getName(), Arrays.asList(s1,s2));
}
};
}
return diff;
} @Test
public void testNam1e() throws Exception
{
// 数据一
List<String> likes = new ArrayList<String>(){
{add("basketball");
add("football");}
}; List<Child> childrens = new ArrayList<Child>(){{
add(new Child("aa",12));
add(new Child("bb",15));
}};
BaseDO sea = new BaseDO("sea", 30, likes, childrens);
sea.setMymap(new HashMap() {{put("xx22","1"); put("xx1","2"); put("xx2","12"); put("xxxx2","12");}});
sea.setChildx(new Child("xx",12)); // 数据二
List<String> likes1 = new ArrayList<String>(){
{add("Table tennis");
add("football");}
}; List<Child> childrens1 = new ArrayList<Child>(){{
add(new Child("aa",12));
add(new Child("cc",12));
add(new Child("bb",16));
}};
BaseDO sea1 = new BaseDO("sea", 31, likes1, childrens1);
sea1.setMymap(new HashMap() {{put("xx","1"); put("xx1","2"); put("xx2","12");}});
sea1.setChildx(new Child("xxx",12));
//比较
JSONObject diff = getDiff(sea, sea1);
System.err.println(diff); } }
测试结果:
{"childrens":[[{"age":15,"name":"bb"}],[{"age":12,"name":"cc"},{"age":16,"name":"bb"}]],"childx":{"name":["xx","xxx"]},"mymap":[{"xxxx2":"12","xx22":"1"},{"xx":"1"}],"age":["30","31"],"likes":[["basketball"],["Table tennis"]]}
Java 比较两个对象的不同之处(old, new) 包含 bean 对象下的 list, Map , bean 的细节的更多相关文章
- java比较两个对象是否相等的方法
java比较两个对象是否相等直接使用equals方法进行判断肯定是不会相同的. 例如: Person person1 =new Person("张三"); Person pe ...
- java中两个对象间的属性值复制,比较,转为map方法实现
package com.franson.study.util; import java.lang.reflect.InvocationTargetException; import java.lang ...
- Java 判断两个对象是否相等
一.使用 == 与 equals == : 它的作用是判断两个对象的地址是不是相等.即,判断两个对象是不是同一个对象.(基本数据类型==比较的是值,引用数据类型==比较的是内存地址) equals() ...
- java使double保留两位小数的多方法 java保留两位小数
这篇文章主要介绍了java使double类型保留两位小数的方法,大家参考使用吧 复制代码 代码如下: mport java.text.DecimalFormat; DecimalFormat d ...
- java保留两位小数
java保留两位小数问题: 方式一: 四舍五入 double f = 111231.5585; BigDecimal b = new BigDecimal(f); d ...
- [原创]java WEB学习笔记59:Struts2学习之路---OGNL,值栈,读取对象栈中的对象的属性,读取 Context Map 里的对象的属性,调用字段和方法,数组,list,map
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- java中两种类型变量
Java中有两种类型的变量,一种是对象类型,另一种是基础类型(primitive type). 对象类型普遍采用引用的方式,比如 List a = new ArrayList(); List b = ...
- Java 交换两个变量的数值
一.参数传递方法 为解决标题问题,首先介绍参数传递方法.目前各类程序设计语言的参数传递方法主要有三种: 按值传递 按引用传递 按指针传递 其中按值传递表示方法(函数)接收的是调用者提供的变量的拷贝,不 ...
- Java中两种实现多线程方式的对比分析
本文转载自:http://www.linuxidc.com/Linux/2013-12/93690.htm#0-tsina-1-14812-397232819ff9a47a7b7e80a40613cf ...
- JAVA之旅(四)——面向对象思想,成员/局部变量,匿名对象,封装 , private,构造方法,构造代码块
JAVA之旅(四)--面向对象思想,成员/局部变量,匿名对象,封装 , private,构造方法,构造代码块 加油吧,节奏得快点了 1.概述 上篇幅也是讲了这点,这篇幅就着重的讲一下思想和案例 就拿买 ...
随机推荐
- holiday04
第四天 查看文件内容 命令 英文 作用 cat 文件名 concatenate 查看.创建.合并.追加文件等功能 more 文件名 more 分屏显示文件内容 grep 搜索文本 文件名 grep 搜 ...
- STM32 获取系统时钟频率
//定义一个RCC_ClocksTypeDef 的结构体 RCC_ClocksTypeDef get_rcc_clock; //调用RCC_GetClocksFreq获取系统时钟状态 RCC_GetC ...
- 逆向学习物联网-网关ESP8266-04系统联合调试
1.测试平台原理 2.搭建硬件测试平台 3.软件测试平台 1)串口终端 2)串口监视 3)OneNET后台服务 https://open.iot.10086.cn/passport/login/ 户名 ...
- 7种实现web实时消息推送的方案
做了一个小破站,现在要实现一个站内信web消息推送的功能,对,就是下图这个小红点,一个很常用的功能. 不过他还没想好用什么方式做,这里我帮他整理了一下几种方案,并简单做了实现. 什么是消息推送(pus ...
- C语言博客作业07
1.作业头 这个作业属于哪个课程 https://edu.cnblogs.com/campus/zswxy/SE2020-3 这个作业要求在哪里 https://edu.cnblogs.com/cam ...
- defer和async区别
浏览器会立即加载JS文件并执行指定的脚本,"立即"指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行 加上async属性,加载 ...
- 项目实训 DAY 10
今天,我写了一些前端代码规范,并按规范修改了一下代码.规范写到了README.md上
- dotnet 项目生成自签名证书
解决dotnet 项目浏览器不安全提示 dotnet dev-certs - 生成自签名证书,以便在开发中使用 HTTPS. dotnet dev-certs https --clean dotnet ...
- 主要转引本地的pycharm如何与服务器连接
需求:本地电脑pycharm上编写程序,在服务器端运行代码. 主要参考了这两篇文章: 1. https://blog.csdn.net/qq_43391414/article/details/1205 ...
- 20200926--矩阵转置(奥赛一本通P95 8 多维数组)
输入一个n行m列的矩阵A,输出它的转置(看下面说明) 输入:第1行包含两个整数n和m(1<=n<=100,1<=m<=100),表示矩阵A的行数和列数.接下来n行,每行m个整数 ...