//
// 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 }

 

原文地址:http://www.cnblogs.com/xiazy/p/16900311.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性