反射比较两个对象属性名相同值不同
Posted 好大的月亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射比较两个对象属性名相同值不同相关的知识,希望对你有一定的参考价值。
概述
有时会遇到获取一个class下2个对象相同属性的不同值的属性。方便在页面上展示差异属性,标识个颜色啥的。
代码Demo
package xxx.xxx.xxx.xxx;
import com.xxx.xxx.xxx.ProductSkuBaseInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import java.beans.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Slf4j
public class Util
public static void main(String[] args)
ProductSkuBaseInfoVO source = new ProductSkuBaseInfoVO();
source.setCategoryId(111L);
source.setDepartmentId(222L);
ProductSkuBaseInfoVO target = new ProductSkuBaseInfoVO();
target.setCategoryId(112L);
target.setDepartmentId(322L);
List<String> list = compareDiffField(source, target);
System.out.println(list);
public static List<String> compareDiffField(Object source, Object target, String... ignoreFiledNames)
List<String> diffFieldNames = new ArrayList<>(20);
if(Objects.isNull(source) || Objects.isNull(target))
return diffFieldNames;
Class<?> sourceClass = source.getClass();
Class<?> targetClass = target.getClass();
BeanInfo sourceBeanInfo = null;
BeanInfo targetBeanInfo = null;
try
//一段时间内可以重复使用,内部get时候的 beanInfoCache 是一个WeakHashMap,每次gc被回收
sourceBeanInfo = Introspector.getBeanInfo(sourceClass);
targetBeanInfo = Introspector.getBeanInfo(targetClass);
catch (IntrospectionException e)
log.error("获取对象BeanInfo失败");
return diffFieldNames;
List<PropertyDescriptor> sourcePropertyDescriptors = Arrays.asList(sourceBeanInfo.getPropertyDescriptors());
Map<String, PropertyDescriptor> targetPropertyDescriptorMap = Stream
.of(targetBeanInfo.getPropertyDescriptors())
.collect(
Collectors.toMap(
FeatureDescriptor::getName,
it -> it,
(k1, k2) -> k2
)
);
if(ArrayUtils.isNotEmpty(ignoreFiledNames))
//忽略指定的属性的比较
sourcePropertyDescriptors = sourcePropertyDescriptors
.stream()
.filter(it -> !ArrayUtils.contains(ignoreFiledNames, it.getName()))
.collect(Collectors.toList());
for (PropertyDescriptor sourcePropertyDescriptor : sourcePropertyDescriptors)
String propertyName = sourcePropertyDescriptor.getName();
PropertyDescriptor targetPropertyDescriptor = targetPropertyDescriptorMap.get(propertyName);
if(Objects.isNull(targetPropertyDescriptor))
//目标对象不存在此属性
continue;
Method sourceReadMethod = sourcePropertyDescriptor.getReadMethod();
Method targetReadMethod = targetPropertyDescriptor.getReadMethod();
if(Objects.isNull(sourceReadMethod) || Objects.isNull(targetReadMethod))
//未找到get方法
continue;
try
Object sourceReadValue = sourceReadMethod.invoke(source);
Object targetReadValue = targetReadMethod.invoke(target);
if(!Objects.equals(sourceReadValue, targetReadValue))
//收集值有差异的属性name
diffFieldNames.add(propertyName);
catch (IllegalAccessException | InvocationTargetException e)
log.error("比较获取不同属性方法出现异常,e:0", e);
return diffFieldNames;
以上是关于反射比较两个对象属性名相同值不同的主要内容,如果未能解决你的问题,请参考以下文章