java:对比两个任意复杂对象的属相是否相等(递归法)

一、背景介绍

        最近重构一个项目,需要对比出旧系统和新系统对外提供接口的返回值是否相同,算是保障新系统正确上线吧。测开部门有专门的接口对比接口,为了保险,自己也写了一个对比两个对象是否相同,关于其他细节本文忽略,本文主要说对比两个对象是否相同。把差异输出出来,乍一听,对比两个对象蛮简单的,但是如果对象结构比较复杂,对比还是比较麻烦的,比如List嵌套Map,Map嵌套List,而且不能够确定嵌套的深度,代码该如何写。

二、代码

         废话不多说直接上代码,可以自行测试,支持List,Map,以及普通对象之间的相互嵌套。采用递归,自己测了几次还管用着

1、DiffExecute.class 就是实现对象对比的细节
public class DiffExecute {
    

    /**
     * 对比接口结果
     * @param carsourceObj
     * @param popObj
     * @return
     */
    public boolean diffObject(String diffName, Object carsourceObj, Object popObj, List<NcDiffRecord> diffRecords) {
        if (carsourceObj == null && popObj == null) {
            return true;
        }
        if (isBaseType(carsourceObj, popObj)) {
            if (carsourceObj != null && !carsourceObj.equals(popObj)) {
                addNcDiffRecord(carsourceObj, popObj, diffName, diffRecords);
                return false;
            }else if (popObj != null && !popObj.equals(carsourceObj)) {
                addNcDiffRecord(carsourceObj, popObj, diffName, diffRecords);
                return false;
            } else {
                return true;
            }
        }
        // 旧结果是list
        if (carsourceObj instanceof List) {
            // 新结果不是list报错
            if (!(popObj instanceof List)) {
                addNcDiffRecord(carsourceObj, popObj, diffName+"的类型不同"+"<oldClass>=["+carsourceObj.getClass()+"]<newClass>=["+popObj.getClass()+"]", diffRecords);
                return false;
            }
            Boolean result = true;
            List carsourList = (List) carsourceObj;
            List popList = (List) popObj;
            if (carsourList.size() != popList.size()) {
                addNcDiffRecord(carsourceObj, popObj, diffName+"的集合长度不同", diffRecords);
                return false;
            }
            for (int i = 0; i < carsourList.size(); i++) {
                result = diffObject("list", carsourList.get(i), popList.get(i), diffRecords) && result;
            }
            return result;
        }
        // 旧的不是list,新结果如果是list那么就报错
        if (popObj instanceof List) {
            addNcDiffRecord(carsourceObj, popObj, diffName+"的类型不同"+"<oldClass>=["+carsourceObj.getClass()+"]<newClass>=["+popObj.getClass()+"]", diffRecords);
            return false;
        }

        Boolean result = true;
        Map<String, Object> carsourceMap = JSONObject.parseObject(JSONObject.toJSONString(carsourceObj));
        Map<String, Object> popMap = JSONObject.parseObject(JSONObject.toJSONString(popObj));
        if (carsourceMap.size() != popMap.size()) {
            addNcDiffRecord(carsourceObj, popObj, diffName+"对象属性数量不同", diffRecords);
            return false;
        }
        Set<String> keySet = carsourceMap.keySet();
        for (String carsourceKey : keySet) {
            // 属性缺失的情况
            if (!popMap.containsKey(carsourceKey)) {
                addNcDiffRecord(carsourceMap.get(carsourceKey), null, "新结果没有属性为["+carsourceKey+"]的值", diffRecords);
                continue;
            }
            result = diffObject(carsourceKey, carsourceMap.get(carsourceKey), popMap.get(carsourceKey), diffRecords) && result;
        }
        return result;
    }

    private boolean isBaseType(Object carsourceObj, Object popObj) {
        if (carsourceObj instanceof String) {
            return true;
        } else if (carsourceObj instanceof Integer) {
            return true;
        } else if (carsourceObj instanceof Character) {
            return true;
        } else if (carsourceObj instanceof Boolean) {
            return true;
        } else if (carsourceObj instanceof Long){
            return true;
        } else if (carsourceObj instanceof Byte) {
            return true;
        } else if (carsourceObj instanceof Double) {
            return true;
        } else if (carsourceObj instanceof Float) {
            return true;
        } else if (carsourceObj instanceof Short){
            return true;
        } else {
            return false;
        }
    }

    public void addNcDiffRecord(Object carsourceObj, Object popObj, String diffName, List<NcDiffRecord> diffRecords) {
        NcDiffRecord record = new NcDiffRecord();
        record.setExpectValue(JSONObject.toJSONString(carsourceObj));
        record.setActualValue(JSONObject.toJSONString(popObj));
        record.setNewDiffItemName(diffName);
        record.setOldDiffItemName(diffName);
        diffRecords.add(record);
    }

}

2、NcDiffRecord.class  主要记录差异的结果的

public class NcDiffRecord implements Serializable {
    
    private Integer id;
    
    private Byte isDeleted;

    
    private Integer diffDependId;

    private String newDiffItemName;

    private String oldDiffItemName;
    private String expectValue;
    private String actualValue;

}

3、DiffExecuteTest.class  是测试类,为了大家好看,用来一个很简单的两个对象,大家可以自己造对象,进行对比。

public class DiffExecuteTest {
    @Resource
    private DiffExecute diffExecute;

    
    @Test
    public void diffOneObject() {
        DiffExecute diffExecute = new DiffExecute();
        List<NcDiffRecord> result = Lists.newArrayList();

        GroupCityDTO cityDTO5 = new GroupCityDTO();
        cityDTO5.setCityCount(2);
        cityDTO5.setCityGroupAlias("你妹");
        cityDTO5.setCityIds(Lists.newArrayList(1,2,3));
        cityDTO5.setCityNames("猪你妹");
        cityDTO5.setCityGroupId(2312);

        GroupCityDTO cityDTO6 = new GroupCityDTO();
        cityDTO6.setCityCount(3);
        cityDTO6.setCityGroupAlias("呱你妹");
        cityDTO6.setCityIds(Lists.newArrayList(1,3));
        cityDTO6.setCityNames("猪你妹");
        cityDTO6.setCityGroupId(23132);
        diffExecute.diffObject("",cityDTO5, cityDTO6, result );
        System.out.println(result);

    }

是不是很简单嘞!,嘿嘿,奥利给,对了,有啥问题,给我提建议。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值