BeanInfo反射比较两个对象属性名相同值不同

概述

有时会遇到获取一个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;
    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值