//
// 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 对象比较 返回不相同的值的更多相关文章

  1. 使用Gson转换json数据为Java对象的一个例子

    记录工作中碰到的一个内容. 原料是微信平台的一个接口json数据. { "errcode" : 0, "errmsg" : "ok", &q ...

  2. java 对象序列化 RMI

    对于一个存在于Java虚拟机中的对象来说,其内部的状态只保持在内存中.JVM停止之后,这些状态就丢失了.在很多情况下,对象的内部状态是需要被持久化下来的.提到持久化,最直接的做法是保存到文件系统或是数 ...

  3. Java对象序列化与RMI

    对于一个存在于Java虚拟机中的对象来说,其内部的状态只保持在内存中.JVM停止之后,这些状态就丢失了.在很多情况下,对象的内部状态是需要被持久化下来的.提到持久化,最直接的做法是保存到文件系统或是数 ...

  4. Android Studio NDK 新手教程(5)--Java对象的传递与改动

    概述 本文主要Java与C++之间的对象传递与取值.包括传递Java对象.返回Java对象.改动Java对象.以及性能对照. 通过JNIEnv完毕数据转换 Java对象是存在于JVM虚拟机中的,而C+ ...

  5. java hashCode方法返回值

    hashCode 是和内存地址相关的一个整数. HashCode只是在需要用到哈希算法的数据结构中才有用 用途是为了方便快速地查找对象: HashMap 是根据键对象的 HashCode 来进行快速查 ...

  6. java对象的内存布局(二):利用sun.misc.Unsafe获取类字段的偏移地址和读取字段的值

    在上一篇文章中.我们列出了计算java对象大小的几个结论以及jol工具的使用,jol工具的源代码有兴趣的能够去看下.如今我们利用JDK中的sun.misc.Unsafe来计算下字段的偏移地址,一则验证 ...

  7. 在Java 线程中返回值的用法

    http://icgemu.iteye.com/blog/467848 在Java 线程中返回值的用法 博客分类: Java Javathread  有时在执行线程中需要在线程中返回一个值:常规中我们 ...

  8. 10-02 Java 形式参数和返回值的问题深入研究,链式编程

    形式参数和返回值的问题: 1:形式参数和返回值的问题(理解) (1)形式参数: 类名:需要该类的对象 抽象类名:需要该类的子类对象 接口名:需要该接口的实现类对象 (2)返回值类型: 类名:返回的是该 ...

  9. 定义一个复数(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 ...

  10. java 代码执行cmd 返回值异常 (关于JAVA Project.waitfor()返回值是1)

    关于JAVA Project.waitfor()返回值是1   0条评论 Project.waitfor()返回值是1,找了很久从网上没有发现关于1的说明. 这时对源代码调试了一下,发现Project ...

随机推荐

  1. yarn 更新依赖包

    yarn upgrade --latest 其他的以后再记录.

  2. IDEA 项目运行内存设置

    IDEA 运行内存设置 1.堆内存设置 2.help ---- edit custom VM options 参考摘录:https://blog.csdn.net/wentaolv/article/d ...

  3. MyBatis_01(前置知识)

    1-学习思路(课程主要内容): 2-MyBatis特性 3- MyBatis下载 但是我们在使用MyBatis的时候,都是直接 "Maven导入MyBatis的jar包" (所以, ...

  4. Stream流、lambda表达式、方法引用、构造引用

    函数式接口 函数接口为lambda表达式和方法引用提供目标类型,就是提供支持的接口里面只有且必须只有一个抽象方法, 如果接口只有一个抽象方法,java默认他为函数式接口 @FunctionalInte ...

  5. 从零搭建hadoop集群之hadoop集群安装

    1.集群规划   HDSF YARN hadoop01 NanemNode(主机点),DataNode NodeManager hadoop02 DataNode, SecondaryNamenode ...

  6. ts的装饰器

    console.log('装饰器.......') // 装饰器就是一个方法,可以注入到类,方法,属性上来拓展类,属性,方法,参数的功能 // 常见:类装饰器,属性装饰器,方法装饰器,参数装饰器 // ...

  7. 爬qqhentai

    import requestsfrom bs4 import BeautifulSoupimport timeimport reimport osimport randomagentlist = [& ...

  8. springboot配置文件中的基本配置

    #应用启动端口设置server.port=9088#=================================微信相关====================================# ...

  9. vs2019 文件读取操作

    1 #include<stdio.h> 2 #define INF 10000000 3 int main() 4 { 5 FILE* fin , * fout ; 6 errno_t a ...

  10. HttpClient psot和get请求

    private String backAllUserInfo(String uid) throws IOException { //this.setInterfaceurl("/idm/js ...