前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JAVA 通用寻找对象间差异的所有字段

JAVA 通用寻找对象间差异的所有字段

作者头像
星痕
发布2020-04-01 17:54:24
2.6K0
发布2020-04-01 17:54:24
举报
文章被收录于专栏:JAVA后端开发

最近在做某个项目中,需要查找多个属性间不同的字段,但这些属性很多,一个一个的字段比较,很折腾,所以就自己写了一个快速的框架. 1.定义需要对比的结果,有新增,变更,删除,无变化四种结果

代码语言:javascript
复制
   public enum  CompareStatus {
    /**
     * 标记新数据
     */
    NEW,
    /**
     * 标记变更数据
     */
    CHANGE,
    /**
     * 标记删除数据
     */
    DELETE,
    /**
     * 标记没有变更
     */
    NO_CHANGE;

}
  1. 定义对比的结果类
代码语言:javascript
复制
    @AllArgsConstructor
@NoArgsConstructor
@Data
public class CompareResult {

    /**
     * 差异的结果属性
     */
    private String propertyName;
    /**
     * 原来的属性
     */
    private Object originalValue;


    /**
     *  当前的属性
     */
    private Object currentValue;
}
  1. 具体对比的结果方法及实现
代码语言:javascript
复制
@Data
@Slf4j
public class CompareObject<T> {


    private CompareStatus status;
    /**
     * 之前原始的值
     */
    private T original;
    /**
     * 当前的值
     */
    private T current;

    /**
     * 需要对比的属性
     */
    private List<String> includePropertys = new ArrayList<>();

    /**
     * 需要排除的属性
     */
    private List<String> excludePropertys = new ArrayList<>();

    /**
     * 不相等的比较结果
     */
    private List<CompareResult> noEqualCompareResults = new ArrayList<>();


    /**
     * 值相同比较结果
     */
    private List<CompareResult> equalCompareResults = new ArrayList<>();

    /**
     * 计算比较结果
     * @param cls 比较的类
     */
    public void compareDiff(Class<T> cls) {

        Assert.notNull(this.current, "不允许当前比较对象为空");
        boolean isEqual = true;
        //clazz.getDeclaredFields()不能获取父的属性
        Field[] fields = this.getAllFields(cls);
        for(Field field : fields) {
            try {
                //判断属性是否在包含的属性里面
                if (CollectionUtils.isNotEmpty(this.includePropertys) && !this.includePropertys
                        .contains(field.getName())) {
                    continue;
                }
                //判断属性是否在排除的包含属性里面
                if (CollectionUtils.isNotEmpty(this.excludePropertys) && this.excludePropertys
                        .contains(field.getName())) {
                    continue;
                }
                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), cls);
                Method getMethod = pd.getReadMethod();
                Object o1 = this.original == null ? null : getMethod.invoke(this.original);
                Object o2 = this.current == null ? null : getMethod.invoke(this.current);
                CompareResult compareResult = new CompareResult(field.getName(), o1, o2);
                //判断是否有自定义注解
                if (field.getDeclaredAnnotation(CompareSpi.class) != null) {
                    CompareSpi compareSpi = field.getDeclaredAnnotation(CompareSpi.class);
                    //自定义比较内容
                    CompareSpiService compareSpiService = (CompareSpiService) compareSpi.compareClass().newInstance();
                    if (compareSpiService.compareObject(o1, o2)) {
                        this.equalCompareResults.add(compareResult);
                    } else {
                        isEqual = false;
                        this.noEqualCompareResults.add(compareResult);
                    }
                } else {
                    if (Objects.equals(o2, o1)) {
                        this.equalCompareResults.add(compareResult);
                    } else {
                        isEqual = false;
                        this.noEqualCompareResults.add(compareResult);
                    }
                }
            } catch (Exception e) {
             log.debug(e.getMessage());
            }
        }
        if (this.original == null) {
            this.status = CompareStatus.NEW;
        } else if (isEqual) {
            this.status = CompareStatus.NO_CHANGE;
        } else {
            this.status = CompareStatus.CHANGE;
        }

    }

    private Field[] getAllFields(Class clazz) {
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }


 
}
  1. 测试具体调用的方法
代码语言:javascript
复制
        BaseModel orgDepartmentDto = new BaseModel();
        orgDepartmentDto.setCreateUserCode("1111");
        BaseModel orgDepartmentDto2 = new BaseModel();
        orgDepartmentDto2.setCreateUserCode("122211");
        CompareObject<BaseModel> compareObject = new CompareObject<>();
        compareObject.setCurrent(orgDepartmentDto);
        compareObject.setOriginal(orgDepartmentDto2);
        compareObject.compareDiff(BaseModel.class);
        log.info(compareObject.getStatus().name());
        log.info(compareObject.getEqualCompareResults().toString());
        log.info(compareObject.getNoEqualCompareResults().toString());

自此,就能快速的获取两个对象的差异,面不需要一个一个的比较

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云服务器利旧
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档