对象字段比较工具方法

一、背景
当两个对象有多个字段需要逐个比较时,为了避免使用多个if分支进行比较,需要使用工具类进行包装,减少代码开发量

二、详细方案
方案一:ObjectMapper工具
代码详情

@Data
   public static class A {

       private Long id;

       private String name;

//        private LocalDateTime time;

   }

   @com.fasterxml.jackson.annotation.JsonFilter("myObjectFilter")
   private static class ObjectMixin {
   }

   private static final ObjectMapper MAPPER = new ObjectMapper();

   public static void main(String[] args) {
		//需要排除字段
       SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.serializeAllExcept("id");
       //过滤器
       FilterProvider filters = new SimpleFilterProvider().addFilter("myObjectFilter", filter);

       final LocalDateTime now = LocalDateTime.now();
       final A a = new A();
       a.setName("haha");
       a.setTime(now);
       final A b = new A();
       b.setName("hehe");
       b.setTime(now);

       try {

           MAPPER.addMixIn(A.class, ObjectMixin.class);

           String jsonString1 = MAPPER.writer(filters).writeValueAsString(a);
           String jsonString2 = MAPPER.writer(filters).writeValueAsString(b);
           System.out.println(jsonString1);
           System.out.println(jsonString2);
           System.out.println(jsonString1.equals(jsonString2));
       } catch (JsonProcessingException e) {
           e.printStackTrace();
       }

   }

方案二:org.springframework.beans.BeanWrapperImpl工具
代码详情
1、工具类

 /**
     * 将Bean对象转换为属性映射的键值对
     *
     * @param oldBean       旧的Bean对象
     * @param newBean       新的Bean对象
     * @param excludeFields 需要排除的字段列表
     * @param <T>           Bean对象的类型
     * @return 包含旧Bean对象属性映射和新Bean对象属性映射的键值对
     */
    private <T> Pair<Map<String, Object>, Map<String, Object>> convertBean(T oldBean,
                                                                           T newBean,
                                                                           List<String> excludeFields) {
        final BeanWrapperImpl oldBeanWrapper = new BeanWrapperImpl(oldBean);
        final BeanWrapperImpl newBeanWrapper = new BeanWrapperImpl(newBean);

        Map<String, Object> oldMap = getPropertyMap(oldBeanWrapper, excludeFields);
        Map<String, Object> newMap = getPropertyMap(newBeanWrapper, excludeFields);

        return Pair.of(oldMap, newMap);
    }

    /**
     * 获取Bean对象的属性映射
     * 只需要原生的字段,不需要class字段
     *
     * @param beanWrapper   Bean对象的包装器
     * @param excludeFields 需要排除的字段列表
     * @return 属性映射的键值对
     */
    private Map<String, Object> getPropertyMap(BeanWrapperImpl beanWrapper, List<String> excludeFields) {
        Map<String, Object> propertyMap = new HashMap<>();
        PropertyDescriptor[] propertyDescriptors = beanWrapper.getPropertyDescriptors();
        for (PropertyDescriptor descriptor : propertyDescriptors) {
            String name = descriptor.getName();
            if (!excludeFields.contains(name) && !CLASS.equals(name)) {
                Object propertyValue = beanWrapper.getPropertyValue(name);
                propertyMap.put(name, propertyValue);
            }
        }
        return propertyMap;
    }```
2、详细使用

```java
 private void compareMiddleData(YqDataMiddleData oldMiddleData,
                                   YqDataMiddleData newMiddleData) {
        Long leafId = oldMiddleData.getLeafId();
        //排除不比较字段
        final List<String> excludeFields = Arrays.asList("id", "washTime", "nluAttitude",
                "extraData", "marks", "createTime", "updateTime");

        // 将两个对象转换为Map,排除不比较的字段
        Pair<Map<String, Object>, Map<String, Object>> mapBeanPair =
                convertBean(oldMiddleData, newMiddleData, excludeFields);
        Map<String, Object> oldMap = mapBeanPair.getLeft();
        Map<String, Object> newMap = mapBeanPair.getRight();

        // 比较中间数据表的详细字段,遍历旧数据的Map,如果对应的值与新数据的Map中的值不相等,则记录日志并触发Cat事件。
        oldMap.forEach((k, v) -> {
            if (!v.equals(newMap.get(k))) {
                log.warn("中间数据比对不通过, 字段:{}", k);
                Cat.logEvent(MIDDLE_DATA_COMPARE_RESULT, String.valueOf(leafId));
            }
        });
    }``
  

   
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值