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.概述 上篇幅也是讲了这点,这篇幅就着重的讲一下思想和案例 就拿买 ...
随机推荐
- vue v-for 使用
html <div> <el-button @click="addListItem" type="primary" style="p ...
- mac_office2019
mac_office2019下载 1,链接地址: mac_office2019: https://590m.com/d/28636472-44062040-dc385f (访问密码:7410) 2, ...
- Access-Control-Allow-Origin php跨域报错
Access-Control-Allow-Origin php跨域 解决办法: 1.PHP中echo:header(""Access-Control-Allow-Origin: * ...
- window.parent.postMessage 解决iframe父子页面域名不一样出现的跨域问题
window.parent.postMessage 解决iframe父子页面域名不一样出现的跨域问题 内嵌 iframe 页面,一般使用 window.parent 或 window.top 来获取父 ...
- 解决 使用 params 传递参数 必须 加上 name
{path:'/blog',name:'blog',params:{is:true}}
- linux下使用bt-rm 限速删除文件
下载限速删除工具: 链接:https://pan.baidu.com/s/1xXu4Hzr99wLlipqxVkXkBg 密码:upbe nohup ./bt-rm -l 10 ${文件地址} &am ...
- 接口自动化(TestNG)
数据驱动概念: 用户输入输出数据来判断测试用例是否通过从而验证需求的测试. 一.接口自动化框架搭建(TestNG数据驱动) ---parameter 关键代码: <?xml version=&q ...
- 零知识证明(Zero-Knowledge Proof)
零知识证明(Zero Knowledge Proof)指的是,证明的人可以向验证的人,在不透露任何有用信息的情况下,使得验证者相信该结论是对的. 三种零知识证明技术:zk-SNARKs, Zk-STA ...
- 从xml读取gps数据获取经纬高
#!/usr/bin/python # -*- coding: UTF-8 -*- from xml.dom.minidom import parse import xml.dom.minidom & ...
- (1)从txt读取GPS数据 真实GPS和slam定位GPS匹配 坐标系ecef和enu转化 计算均方根误差和单帧误差
#!/usr/bin/python # -*- coding: UTF-8 -*- import numpy as np import os #==========================1坐 ...