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.概述 上篇幅也是讲了这点,这篇幅就着重的讲一下思想和案例 就拿买 ...
随机推荐
- Django+VUE.js实现图片上传
vue里的代码 <template> <div> 添加商品<input v-model="name"><br> 价格<inpu ...
- Software--Java--远程调试
Java 远程调试的原理是两个 VM 之间通过debug 协议进行通信,然后以达到远程调试的目的.两者之间可以通过socket进行通信. 步骤: 1. 首先被 debug 程序的虚拟机在启动时要开启d ...
- 自定义go语言日志输出
自定义输出符合下列需求: 1.含两类日志输出方式:调试模式下输出到控制台:生产环境输出到日志文件 2.调用不同的函数/方法构造不同的输出方式,后续只需调用日志级别对应的函数即可输出该级别日志 工具构造 ...
- jenkins +docker+python接口自动化之jenkins容器下安装python项目所需要的库(三)
1.场景 1.centos系统,在docker的jenkins容器下安装python项目所需要的包 2.我们目前是搞接口自动化,代码放到码云上,运行环境是jenkins容器下,所以需要在jenkins ...
- 解决xpath提取的数据列表,保存时不能一一对应的问题
"""拉链函数,zip将几个列表的数据进行封装,一一对应.如果一方列表的数据,比另一方少,那么按数据少的一方对应"""# 数据个数对应相等l ...
- 删除没有刀路的刀具.txt
1 UF_initialize(); 2 std::vector<tag_t>tool_tag; 3 std::vector<tag_t>del_tag; 4 tag_t ...
- Dubbo Debug大全
com.alibaba.dubbo.rpc.RpcException: No provider available from registry 120.25.85.89:2181 for servic ...
- eureka注册中心增加登录认证
https://www.cnblogs.com/gxloong/p/12364523.html 开启Eureka注册中心认证 1.目的描述 Eureka自带了一个Web的管理页面,方便我们查询注册 ...
- Android中的特殊权限
AndroidManifest中定义的权限分为普通权限,危险权限和特殊权限. 普通权限指的是不会威胁到用户的安全和隐私的权限,只需要在AndroidManifest中声明一下就能直接使用. 危险权限指 ...
- 解决nios eclipse报错: WARNING: Couldn't compute FAST_CWD pointer的方法
几天照着书上的例子弄nios的开发流程,编译的时候遇见了这个问题 WARNING: Couldn't compute FAST_CWD pointer 在网上找了大半天解决方法,如下: 链接:http ...