java 对象比较 返回不相同的值
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
// package com.soooft.common.equator; import java.util.List; public interface Equator {
/**
* 比较两个对象是否相同
*
* @param var1
* @param var2
* @return
*/
boolean isEquals(Object var1, Object var2); /**
* 对象比较 支持对象嵌套比较 返回不同值
*
* @param var1
* @param var2
* @return
*/
List<FieldInfo> getDiffFields(Object var1, Object var2);
}
1 package com.soooft.common.equator;
2
3 import java.util.*;
4 import java.util.stream.Collectors;
5 import java.util.stream.Stream;
6 /**
7 * @author xiazhiyong
8 * @description: TODO
9 * @date 2022/11/17
10 */
11 public abstract class AbstractEquator implements Equator {
12 private List<String> includeFields;
13 private List<String> excludeFields;
14 private boolean bothExistFieldOnly = true;
15
16 public AbstractEquator() {
17 this.includeFields = Collections.emptyList();
18 this.excludeFields = Collections.emptyList();
19 }
20
21 public AbstractEquator(boolean bothExistFieldOnly) {
22 this.includeFields = Collections.emptyList();
23 this.excludeFields = Collections.emptyList();
24 this.bothExistFieldOnly = bothExistFieldOnly;
25 }
26
27 public AbstractEquator(List<String> includeFields, List<String> excludeFields) {
28 this.includeFields = includeFields;
29 this.excludeFields = excludeFields;
30 }
31
32 public AbstractEquator(List<String> includeFields, List<String> excludeFields, boolean bothExistFieldOnly) {
33 this.includeFields = includeFields;
34 this.excludeFields = excludeFields;
35 this.bothExistFieldOnly = bothExistFieldOnly;
36 }
37
38 public boolean isEquals(Object first, Object second) {
39 List<FieldInfo> diff = this.getDiffFields(first, second);
40 return diff == null || diff.isEmpty();
41 }
42
43 protected boolean isFieldEquals(FieldInfo fieldInfo) {
44 if (this.isExclude(fieldInfo)) {
45 return true;
46 } else {
47 return !this.isInclude(fieldInfo) || this.nullableEquals(fieldInfo.getFirstVal(), fieldInfo.getSecondVal());
48 }
49 }
50
51 protected boolean isInclude(FieldInfo fieldInfo) {
52 return this.includeFields == null || this.includeFields.isEmpty() || this.includeFields.contains(fieldInfo.getFieldName());
53 }
54
55 protected boolean isExclude(FieldInfo fieldInfo) {
56 return this.excludeFields != null && !this.excludeFields.isEmpty() && this.excludeFields.contains(fieldInfo.getFieldName());
57 }
58
59 List<FieldInfo> compareSimpleField(Object first, Object second) {
60 boolean eq = Objects.equals(first, second);
61 if (eq) {
62 return Collections.emptyList();
63 } else {
64 Object obj = first == null ? second : first;
65 Class<?> clazz = obj.getClass();
66 return Collections.singletonList(new FieldInfo(clazz.getSimpleName(), clazz, first, second, clazz.getName()));
67 }
68 }
69 Set<String> getAllFieldNames(Set<String> firstFields, Set<String> secondFields) {
70 Object allFields;
71 if (this.isBothExistFieldOnly()) {
72 Stream var10000 = firstFields.stream();
73 secondFields.getClass();
74 allFields = var10000.filter(secondFields::contains).collect(Collectors.toSet());
75 } else {
76 allFields = new HashSet(firstFields);
77 ((Set) allFields).addAll(secondFields);
78 }
79
80 return (Set) allFields;
81 }
82
83 private boolean nullableEquals(Object first, Object second) {
84 return first instanceof Collection && second instanceof Collection ? Objects.deepEquals(((Collection) first).toArray(), ((Collection) second).toArray()) : Objects.deepEquals(first, second);
85 }
86
87 public void setIncludeFields(List<String> includeFields) {
88 this.includeFields = includeFields;
89 }
90
91 public void setExcludeFields(List<String> excludeFields) {
92 this.excludeFields = excludeFields;
93 }
94
95 public void setBothExistFieldOnly(boolean bothExistFieldOnly) {
96 this.bothExistFieldOnly = bothExistFieldOnly;
97 }
98
99 public List<String> getIncludeFields() {
100 return this.includeFields;
101 }
102
103 public List<String> getExcludeFields() {
104 return this.excludeFields;
105 }
106
107 public boolean isBothExistFieldOnly() {
108 return this.bothExistFieldOnly;
109 }
110 }
1 package com.soooft.common.equator;
2
3 import cn.hutool.core.util.ClassUtil;
4 import cn.hutool.core.util.StrUtil;
5 import lombok.extern.log4j.Log4j;
6
7 import java.lang.reflect.Field;
8 import java.util.*;
9
10 /**
11 * @author xiazhiyong
12 * @description: TODO
13 * @date 2022/11/17
14 */
15 @Log4j
16 public class MyFieldBaseEquator extends AbstractEquator {
17 public MyFieldBaseEquator() {
18 }
19
20 /**
21 * 指定包含或排除某些字段
22 *
23 * @param includeFields 包含字段,若为 null 或空集,则不指定
24 * @param excludeFields 排除字段,若为 null 或空集,则不指定
25 */
26 public MyFieldBaseEquator(List<String> includeFields, List<String> excludeFields) {
27 super(includeFields, excludeFields);
28 }
29
30 /**
31 * {@inheritDoc}
32 */
33 @Override
34 public List<FieldInfo> getDiffFields(Object first, Object second) {
35 if (first == second) {
36 return Collections.emptyList();
37 }
38 // 先尝试判断是否为简单数据类型
39 if (isSimpleField(first, second)) {
40 return compareSimpleField(first, second);
41 }
42 Object obj = first == null ? second : first;
43
44 String className = obj.getClass().getName();
45 Class<?> clazz = obj.getClass();
46 List<FieldInfo> diffField = new LinkedList<>();
47 // 获取所有字段
48 Field[] fields = clazz.getDeclaredFields();
49 // 遍历所有的字段
50 for (Field firstField : fields) {
51
52 String fieldName = firstField.getName();
53
54 try {
55 Field secondField = second.getClass().getDeclaredField(fieldName);
56 firstField.setAccessible(true);
57 secondField.setAccessible(true);
58 // 开启访问权限,否则获取私有字段会报错
59 Object firstVal = first == null ? null : firstField.get(first);
60 Object secondVal = secondField.get(second);
61 if (ClassUtil.isBasicType(firstField.getType()) || (firstVal instanceof Collection && secondVal instanceof Collection)) {
62 // 封装字段信息
63 FieldInfo fieldInfo = new FieldInfo(fieldName, firstField.getType(), firstVal, secondVal, className);
64 boolean eq = isFieldEquals(fieldInfo);
65 if (!eq) {
66 // 记录不相等的字段
67 diffField.add(fieldInfo);
68 }
69 } else if (onlyOneNull(firstVal, secondVal)) {
70 FieldInfo fieldInfo = new FieldInfo(fieldName, firstField.getType(), firstVal, secondVal, className);
71 diffField.add(fieldInfo);
72 } else if (Objects.isNull(firstVal) && Objects.isNull(secondVal)) {
73 log.debug("双方都为null,不做记录");
74 } else {
75 if (StrUtil.equals(className, Date.class.getName())) {
76 continue;
77 }
78 diffField.addAll(getDiffFields(firstVal, secondVal));
79 }
80 } catch (IllegalAccessException e) {
81 // 只要调用了 firstField.setAccessible(true) 就不会报这个异常
82 throw new IllegalStateException("获取属性进行比对发生异常: " + fieldName, e);
83 } catch (NoSuchFieldException ignored) {
84
85 }
86 }
87 return diffField;
88 }
89
90 private boolean onlyOneNull(Object firstVal, Object secondVal) {
91 return (Objects.isNull(firstVal) && Objects.nonNull(secondVal)) || (Objects.isNull(secondVal) && Objects.nonNull(firstVal));
92 }
93
94
95 /**
96 * 如果简单数据类型的对象则直接进行比对
97 *
98 * @param first 对象1
99 * @param second 对象2
100 * @return 不同的字段信息,相等返回空集,不等则 FieldInfo 的字段名为对象的类型名称
101 */
102 List<FieldInfo> compareSimpleField(Object first, Object second) {
103 boolean eq = Objects.equals(first, second);
104 if (eq) {
105 return Collections.emptyList();
106 } else {
107 Object obj = first == null ? second : first;
108 Class<?> clazz = obj.getClass();
109 // 不等的字段名称使用类的名称
110 return Collections.singletonList(new FieldInfo(clazz.getSimpleName(), clazz, first, second, clazz.getName()));
111 }
112 }
113
114 /**
115 * 判断是否为原始数据类型
116 *
117 * @param first 对象1
118 * @param second 对象2
119 * @return 是否为原始数据类型
120 */
121 boolean isSimpleField(Object first, Object second) {
122 Object obj = first == null ? second : first;
123 Class<?> clazz = obj.getClass();
124 return clazz.isPrimitive() || ClassUtil.isBasicType(clazz);
125 }
126 }
java 对象比较 返回不相同的值的更多相关文章
- 使用Gson转换json数据为Java对象的一个例子
记录工作中碰到的一个内容. 原料是微信平台的一个接口json数据. { "errcode" : 0, "errmsg" : "ok", &q ...
- java 对象序列化 RMI
对于一个存在于Java虚拟机中的对象来说,其内部的状态只保持在内存中.JVM停止之后,这些状态就丢失了.在很多情况下,对象的内部状态是需要被持久化下来的.提到持久化,最直接的做法是保存到文件系统或是数 ...
- Java对象序列化与RMI
对于一个存在于Java虚拟机中的对象来说,其内部的状态只保持在内存中.JVM停止之后,这些状态就丢失了.在很多情况下,对象的内部状态是需要被持久化下来的.提到持久化,最直接的做法是保存到文件系统或是数 ...
- Android Studio NDK 新手教程(5)--Java对象的传递与改动
概述 本文主要Java与C++之间的对象传递与取值.包括传递Java对象.返回Java对象.改动Java对象.以及性能对照. 通过JNIEnv完毕数据转换 Java对象是存在于JVM虚拟机中的,而C+ ...
- java hashCode方法返回值
hashCode 是和内存地址相关的一个整数. HashCode只是在需要用到哈希算法的数据结构中才有用 用途是为了方便快速地查找对象: HashMap 是根据键对象的 HashCode 来进行快速查 ...
- java对象的内存布局(二):利用sun.misc.Unsafe获取类字段的偏移地址和读取字段的值
在上一篇文章中.我们列出了计算java对象大小的几个结论以及jol工具的使用,jol工具的源代码有兴趣的能够去看下.如今我们利用JDK中的sun.misc.Unsafe来计算下字段的偏移地址,一则验证 ...
- 在Java 线程中返回值的用法
http://icgemu.iteye.com/blog/467848 在Java 线程中返回值的用法 博客分类: Java Javathread 有时在执行线程中需要在线程中返回一个值:常规中我们 ...
- 10-02 Java 形式参数和返回值的问题深入研究,链式编程
形式参数和返回值的问题: 1:形式参数和返回值的问题(理解) (1)形式参数: 类名:需要该类的对象 抽象类名:需要该类的子类对象 接口名:需要该接口的实现类对象 (2)返回值类型: 类名:返回的是该 ...
- 定义一个复数(z=x+iy)类Complex,包含: 两个属性:实部x和虚部y 默认构造函数 Complex(),设置x=0,y=0 构造函数:Complex(int i,int j) 显示复数的方法:showComp()将其显示为如: 5+8i或5-8i 的形式。 求两个复数的和的方法:(参数是两个复数类对象,返回值是复数类对象)public Complex addComp(Compl
因标题框有限,题目未显示完整,以下再放一份: 定义一个复数(z=x+iy)类Complex,包含: 两个属性:实部x和虚部y 默认构造函数 Complex(),设置x=0,y=0 构造函数:Compl ...
- java 代码执行cmd 返回值异常 (关于JAVA Project.waitfor()返回值是1)
关于JAVA Project.waitfor()返回值是1 0条评论 Project.waitfor()返回值是1,找了很久从网上没有发现关于1的说明. 这时对源代码调试了一下,发现Project ...
随机推荐
- win10彻底关闭系统更新 - 禁用 Windows Update Medic Service服务(1803和1809版本)
这几天有点苦恼呀,不,应该说是挺苦恼,我的新本儿到了几天之后,就开始推荐更新,可以我从心里就不想着更新,那么就要阻止它了,按照原来的办法,进行了双重阻止,这在之前是屡试不爽的,但是还是一直在提醒我 ...
- python对文件的处理方法
#1.打开文件 如果文件不存在会报错 file = open("1.txt") #2.使用w.w+.a.a+模式打开,如果文件不存在就创建文件 file = open(" ...
- 【Java学习day04】Java文件的创建和Java代码的执行
Java文件的创建和Java代码的执行 随便新建一个文件夹,存放代码 在新建的文件夹里新建一个java文件 新建一个文本文档 将新建的文本文档重命名为hello.java 注意了!后缀必须改为.jav ...
- js var
var x= new Number(); alert(x)//0 x=new Object(); alert(JSON.stringify(x)) //{} x=new Boolean(); aler ...
- flex height变高了
在做移动端项目时,使用了flex布局后,所有的子项高度变成了一致 问题:在flex布局中,如何保持子项自身高度 原因: Flex 布局会默认: 把所有子项变成水平排列.默认不自动换行.让子项与其内容等 ...
- win11装wsl ubuntu操作记录
应用商店安装Windows Subsystem for Linux Preview ubuntu 查看已经安装的WSL版本,以及分发版对应的VERSION wsl -l -v 看到Ubuntu版本是1 ...
- c#怎样删除指定文件名的文件
我有一个文件夹,里面有6个文件,我现在要删除字母B开头的三个文件,只需要剩下A开头的文件即可用C#怎样操作??? foreach (string d in Directory.GetFileSyste ...
- HDLbits——Exams/2014 q4b
题目要求 使用verilog描述如图所示得移位寄存器: Write a top-level Verilog module (named top_module) for the shift regist ...
- PL/SQL Initialization error Could not initialize 问题
问题: PL/SQL Initialization error Could not initialize 问题 参考链接: https://blog.csdn.net/luoyanjiewade/ar ...
- HttpClient psot和get请求
private String backAllUserInfo(String uid) throws IOException { //this.setInterfaceurl("/idm/js ...