**
* 对象比较工具类
* 基本类型/Java自带类型使用Apache的比较工具类.
* 自定义对象采用反射递归比较.集合类采用循环递归比较
*
*
* Date: 2017/8/9
*/
public class EqualObjectUtils implements Serializable {
private static final long serialVersionUID = 602163719206844077L;
/**
* 对象比较工具类
*
* @param ob1 比较对象1
* @param ob2 比较对象2
* @param ignoreProperNames 忽略属性名List
* @return
*/
public static boolean deepEquals(Object ob1, Object ob2, List ignoreProperNames) {
//对象空值判断
if (ob1 == ob2) return true;
if (ob1 == null || ob2 == null) return false;
Map jugMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(ignoreProperNames)) {
ignoreProperNames.stream().filter(StringUtils::isNotBlank).forEach(v -> jugMap.put(v, true));
}
return deepEquals(ob1, ob2, jugMap);
}
/**
* 比较
*
* @param ob1
* @param ob2
* @param jugMap
* @return
*/
private static boolean deepEquals(Object ob1, Object ob2, final Map jugMap) {
//对象空值判断
if (ob1 == ob2) return true;
if (ob1 == null || ob2 == null) return false;
Class> aClass = ob1.getClass();
Class> bClass = ob2.getClass();
//类型是否一致
if (!Objects.equals(ob1.getClass(), ob2.getClass())) return false;
//是否是集合类
if (isCollection(ob1) || isCollection(ob2)) {
Collection co1 = (Collection) ob1;
Collection co2 = (Collection) ob2;
boolean rs = deepCollectionsEquals(co1, co2, jugMap);
if (!rs) return false;
} else if (isJavaClass(aClass) || isJavaClass(bClass)) {//Java自带对象处理(目前包名已Java开头的采用此方法.)
return EqualsBuilder.reflectionEquals(ob1, ob2, new ArrayList<>(jugMap.keySet()));
} else {//自定义对象处理
//自定义对象
Field[] fields1 = aClass.getDeclaredFields();
Field[] fields2 = bClass.getDeclaredFields();
if (fields1 == fields2) return true;
if (fields1 == null || fields2 == null) return false;
if (fields1.length != fields2.length) return false;
Map fieldMap1 = new HashMap<>();
Map fieldMap2 = new HashMap<>();
for (int i = 0; i < fields1.length; i++) {
Field field1 = fields1[i];
Field field2 = fields2[i];
//过滤指定属性
Boolean aBoolean = jugMap.get(field1.getName());
if (aBoolean != null && aBoolean) continue;
if ("serialVersionUID".equals(field1.getName())) continue;//序列化忽略
field1.setAccessible(true);
field2.setAccessible(true);
fieldMap1.put(field1.getName(), field1);
fieldMap2.put(field2.getName(), field1);
}
Set> entrySet = fieldMap1.entrySet();
for (Iterator> iterator = entrySet.iterator(); iterator.hasNext(); ) {//每个子属性判断
Map.Entry next = iterator.next();
String key = next.getKey();
Field field1 = next.getValue();
Field field2 = fieldMap2.get(key);
Class> type1 = field1.getType();
Class> type2 = field2.getType();
//类型是否一致
if (!Objects.equals(type1, type2)) return false;
Object o1 = null;
Object o2 = null;
try {
o1 = field1.get(ob1);
o2 = field2.get(ob2);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//对象空值判断
if (o1 == o2) continue;
if (o1 == null || o2 == null) return false;
//是否是集合类
if (isCollection(o1) || isCollection(o2)) {
Collection co1 = (Collection) o1;
Collection co2 = (Collection) o2;
boolean rs = deepCollectionsEquals(co1, co2, jugMap);
if (!rs) return false;
} else if (isJavaClass(field1.getType()) || isJavaClass(field1.getType())) {
boolean equals = EqualsBuilder.reflectionEquals(o1, o2, new ArrayList<>(jugMap.keySet()));
if (!equals) return false;
} else {
boolean equals = deepEquals(o1, o2, jugMap);
if (!equals) return false;
}
}
}
return true;
}
/**
* 是否是Java提供的数据类型.可以适当扩展其他类型.只要支持Equal方法的类型都可以添加进来.对工具类没影响
*
* @param _class
* @return
*/
private static boolean isJavaClass(Class _class) {
//基本类型
if (_class.isPrimitive()) {
return true;
}
//包装类型
if (_class.getPackage().getName().startsWith("java.")) {
return true;
}
//自定义类型
return false;
}
/**
* 是否是集合类
*
* @param o
* @return
*/
private static boolean isCollection(Object o) {
if (o instanceof Collection) {
return true;
}
return false;
}
/**
* 集合类比较
*
* @param collection1
* @param collection2
* @return
*/
private static boolean deepCollectionsEquals(Collection collection1, Collection collection2, final Map jugMap) {
if (collection1 == collection2) return true;
if (collection1 == null || collection2 == null) return false;
if (collection1.size() != collection2.size()) return false;
for (Object o1 : collection1) {
boolean rs = false;
for (Object o2 : collection2) {
rs = deepEquals(o1, o2, jugMap);
if (rs) {
rs = true;
}
}
if (!rs) return false;
}
return true;
}
public static void main(String[] args) {
GameRoomDTO room1 = new GameRoomDTO();
GameRoomDTO room2 = new GameRoomDTO();
room1.setGameRoomId(1L);
room2.setGameRoomId(1L);
room1.setRoomName("房间1");
room2.setRoomName("房间1");
Member member1 = new Member();
Member member2 = new Member();
member1.setNickName("小王");
member2.setNickName("小李");
room1.setMemberList(Lists.newArrayList(member2,member1));
room2.setMemberList(Lists.newArrayList(member1,member2));
List ignoreProps = Lists.newArrayList("nickName", "createTime", "updateTime", "lastLoginTime");
System.out.println(deepEquals(room1,room2,ignoreProps));
}
}