// // 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 }
标签:返回,excludeFields,java,includeFields,相同,Object,second,return,first From: https://www.cnblogs.com/xiazy/p/16900311.html