import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
/**
* 对象属性值比较工具
* @author XueYQ
* @date: 2020年8月3日
*/
public class ObjectCompareUtil {
private static Logger log = LoggerFactory.getLogger(ObjectCompareUtil.class);
/**
* 比较两个实体属性值,返回一个boolean,true则表时两个对象中的属性值无差异
* @param oldObject 进行属性比较的对象1
* @param newObject 进行属性比较的对象2
* @return 属性差异比较结果boolean【true:无差异;false:有差异】
*/
public static boolean compareObject(Object oldObject, Object newObject) {
boolean isCompare = true;
Map<String, Map<String,Object>> resultMap = compareFields(oldObject,newObject);
if (!CollectionUtils.isEmpty(resultMap)) {
isCompare = false;
}
return isCompare;
}
/**
* 比较两个实体属性值,返回一个map以有差异的属性名为key,value为一个Map分别存oldObject,newObject此属性名的值
* @param oldObject 进行属性比较的对象1
* @param newObject 进行属性比较的对象2
* @return 属性差异比较结果map
*/
@SuppressWarnings("rawtypes")
public static Map<String, Map<String,Object>> compareFields(Object oldObject, Object newObject) {
Map<String, Map<String, Object>> map = new HashMap<String, Map<String,Object>>(16);
try {
/**
* 只有两个对象都是同一类型的才有可比性
*/
if (oldObject.getClass() == newObject.getClass()) {
Class clazz = oldObject.getClass();
// 获取object的所有属性
PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz, Object.class).getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
// 遍历获取属性名
String name = pd.getName();
// 获取属性的get方法
Method readMethod = pd.getReadMethod();
// 在oldObject上调用get方法等同于获得oldObject的属性值
Object oldValue = readMethod.invoke(oldObject);
// 在newObject上调用get方法等同于获得newObject的属性值
Object newValue = readMethod.invoke(newObject);
// 对象值为空,跳过
if (oldValue == null || newValue == null) {
break;
}
// 时间格式不比较,跳过
if (oldValue instanceof Date || newValue instanceof Date) {
break;
}
if (!oldValue.equals(newValue)) {
// 比较这两个值是否相等,不等就可以放入map了
Map<String, Object> valueMap = new HashMap<String,Object>(16);
valueMap.put("oldValue",oldValue);
valueMap.put("newValue",newValue);
map.put(name, valueMap);
}
}
}
} catch(Exception e) {
log.error("比较两个实体属性值出错;error={}", e.getMessage());
}
return map;
}
}