一、背景介绍
最近重构一个项目,需要对比出旧系统和新系统对外提供接口的返回值是否相同,算是保障新系统正确上线吧。测开部门有专门的接口对比接口,为了保险,自己也写了一个对比两个对象是否相同,关于其他细节本文忽略,本文主要说对比两个对象是否相同。把差异输出出来,乍一听,对比两个对象蛮简单的,但是如果对象结构比较复杂,对比还是比较麻烦的,比如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);
}
是不是很简单嘞!,嘿嘿,奥利给,对了,有啥问题,给我提建议。