适用情况:
两个对象属于同一个类,如果类没有重写equals方法,可通过反射对比对象属性值。如果对象的属性里面包含了数组、List、Set或者Map的时候,只会按顺序去对比这些集合里面的值,
比如里面对象里面有一个List属性,里面的值是 a、b,另外一个对象的属性值是b、a,虽然两个对象的List属性的值都是a、b,但是因为顺序不同,所以这里判断这两个对象值是不同的。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
/**
* @author yjy
* @date 2022/3/29
* 比较两个对象值是否相等
*/
public class BeanCompareUtils {
private static final Logger logger = LoggerFactory.getLogger(BeanCompareUtils.class);
private static List<String> baseTypes= Arrays.asList(
String.class.getName(),
Integer.class.getName(),
Long.class.getName(),
Double.class.getName(),
Float.class.getName(),
BigDecimal.class.getName(),
Date.class.getName(),
Timestamp.class.getName(),
LocalDate.class.getName(),
LocalDateTime.class.getName(),
Boolean.class.getName(),
Short.class.getName(),
Byte.class.getName(),
Character.class.getName(),
BigInteger.class.getName()
);
/**
* 比较两个对象值是否相等
* @param p1
* @param p2
* @return
*/
public static <P> boolean equals(Object p1,Object p2){
if(p1==p2){
return true;
}
else if(p1!=null && p2!=null){
Class cls=p1.getClass();
if(!p1.getClass().equals(p2.getClass())){
return false;
}
//如果是基础类型数据
if(baseTypes.contains(cls.getName())){
return Objects.equals(p1,p2);
}
PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(cls);
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
Method readMethod = propertyDescriptor.getReadMethod();
if(readMethod!=null){
Class<?> propertyType = propertyDescriptor.getPropertyType();
try {
Object value1 = readMethod.invoke(p1);
Object value2 = readMethod.invoke(p2);
//如果是基础类数据
if(propertyType.isPrimitive() || baseTypes.contains(propertyType.getName())) {
if(!Objects.equals(value1, value2)){
return false;
}
}
//如果是数组
else if(propertyType.isArray()){
if(value1==null && value2==null){
}else if(value1!=null && value2!=null ){
boolean b = equalCollection((Object[]) value1, (Object[]) value2);
if(Boolean.FALSE.equals(b)){
return false;
}
}else{
return false;
}
}
//如果是List、Set
else if(Collection.class.isAssignableFrom(propertyType)){
if(value1==null && value2==null){
}else if(value1!=null && value2!=null){
boolean b = equalCollection(((Collection) value1).toArray(), ((Collection) value2).toArray());
if(Boolean.FALSE.equals(b)){
return false;
}
}else{
return false;
}
}
else if(Map.class.isAssignableFrom(propertyType)){
if(value1==null && value2==null){
}else if(value1!=null && value2!=null){
boolean b = equalMap((Map) value1, (Map) value2);
if(Boolean.FALSE.equals(b)){
return false;
}
}else{
return false;
}
}else{
boolean b = equals(value1, value2);
if(Boolean.FALSE.equals(b)){
return false;
}
}
} catch (Exception e){
logger.error("反射获取对象属性值报错",e);
return false;
}
}
}
}else{
return false;
}
return true;
}
private static boolean equalCollection(Object[] c1,Object[] c2){
if(c1.length!=c2.length){
return false;
}
for(int i=0;i<c1.length;i++){
boolean b=equals(c1[i],c2[i]);
if(Boolean.FALSE.equals(b)){
return false;
}
}
return true;
}
private static boolean equalMap(Map m1,Map m2){
if(m1.size()!=m2.size()){
return false;
}
for (Object key : m1.keySet()) {
if(!m2.containsKey(key)){
return false;
}
Object value1 = m1.get(key);
Object value2=m2.get(key);
boolean b=equals(value1,value2);
if(Boolean.FALSE.equals(b)){
return false;
}
}
return true;
}
}