复制两个对象字段类型一样,属性(字段名)不一样

本文介绍了一种利用自定义注解和反射技术实现不同字段对象间的数据拷贝方法,有效解决了对象属性不完全匹配时的复制难题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 两个字段不一样的对象复制
    • 思路:自定义注解获取目标实体类和源实体类的对应关系.通过反射获取值和赋值.
    • 自定义注解
      • /**
         * 对象拷贝注解(自定义注解)
         */
        @Retention(RetentionPolicy.RUNTIME)
        @Target(ElementType.FIELD)
        public @interface CopyField {
            /**
             * 目标数据字段,设置目标属性名
             *
             * @return
             */
            String targetName() default "";
        
            /**
             * 源数据字段,设置源属性名
             *
             * @return
             */
            String originName() default "";
        }
    •  工具类方法:

    • 
      import com.qunji.sale.weblogic.basic.interfaces.CopyField;
      import lombok.extern.slf4j.Slf4j;
      
      import java.beans.IntrospectionException;
      import java.beans.PropertyDescriptor;
      import java.lang.reflect.Field;
      import java.lang.reflect.InvocationTargetException;
      import java.lang.reflect.Method;
      import java.util.HashMap;
      import java.util.Map;
      
      /**
       * @program: 属性赋值工具
       * @description:
       * @author: 单人影
       * @create: 2019/7/25
       **/
      @Slf4j
      public class FieldUtils {
      
          public static void copyBean(Object originBean, Object targetBean) {
              Map<String, Object> originFieldKeyWithValueMap = new HashMap<>(16);
              PropertyDescriptor propertyDescriptor = null;
              //生成源bean的属性及其值的字典
              generateOriginField(propertyDescriptor, originBean, originFieldKeyWithValueMap, originBean.getClass());
              //设置目标bean的属性值
              settingTargetField(propertyDescriptor, targetBean, originFieldKeyWithValueMap, targetBean.getClass());
          }
      
          /**
           * 获取源参数
           *
           * @param propertyDescriptor         属性描述器
           * @param originBean                 待拷贝的bean
           * @param originFieldKeyWithValueMap 存放待拷贝的属性和属性值
           * @param beanClass                  待拷贝的class
           */
          private static void generateOriginField(PropertyDescriptor propertyDescriptor, Object originBean, Map<String, Object> originFieldKeyWithValueMap, Class<?> beanClass) {
              //如果不存在类,那么跳出循环
              if (beanClass.getSuperclass() == null) {
                  return;
              }
              Field[] originFieldList = beanClass.getDeclaredFields();
              for (Field field : originFieldList) {
                  try {
                      //获取属性上的注解。如果不存在,使用属性名,如果存在使用注解名
                      CopyField annotation = field.getAnnotation(CopyField.class);
                      String targetName = "";
                      if (annotation != null) {
                          targetName = annotation.targetName();
                      } else {
                          targetName = field.getName();
                      }
                      //初始化
                      propertyDescriptor = new PropertyDescriptor(field.getName(), beanClass);
                      Method method = propertyDescriptor.getReadMethod();
                      Object value = method.invoke(originBean);
                      //设置值
                      originFieldKeyWithValueMap.put(targetName, value);
                  } catch (IntrospectionException e) {
                      log.warn("【源对象】异常:" + field.getName() + "不存在对应的get方法,无法参与拷贝!");
                  } catch (IllegalAccessException e) {
                      log.warn("【源对象】异常:" + field.getName() + "的get方法执行失败!");
                  } catch (InvocationTargetException e) {
                      log.warn("【源对象】异常:" + field.getName() + "的get方法执行失败!");
                  }
              }
              //生成超类 属性-value
              generateOriginField(propertyDescriptor, originBean, originFieldKeyWithValueMap, beanClass.getSuperclass());
          }
      
          /**
           * @param propertyDescriptor         属性描述器
           * @param targetBean                 目标容器bean
           * @param originFieldKeyWithValueMap 待拷贝的属性和属性值
           * @param beanClass                  待设置的class
           */
          private static void settingTargetField(PropertyDescriptor propertyDescriptor, Object targetBean, Map<String, Object> originFieldKeyWithValueMap, Class<?> beanClass) {
              //如果不存在类,那么跳出循环
              if (beanClass.getSuperclass() == null) {
                  return;
              }
              Field[] targetFieldList = beanClass.getDeclaredFields();
              for (Field field : targetFieldList) {
                  try {
                      //获取属性上的注解。如果不存在,使用属性名,如果存在使用注解名
                      CopyField annotation = field.getAnnotation(CopyField.class);
                      String originName = "";
                      if (annotation != null) {
                          originName = annotation.originName();
                      } else {
                          if ("serialVersionUID".equalsIgnoreCase(field.getName())) {
                              continue;
                          }
                          originName = field.getName();
                      }
                      //初始化当前属性的描述器
                      propertyDescriptor = new PropertyDescriptor(field.getName(), beanClass);
                      Method method = propertyDescriptor.getWriteMethod();
                      method.invoke(targetBean, originFieldKeyWithValueMap.get(originName));
                  } catch (IntrospectionException e) {
                      log.warn("【目标对象】异常:" + field.getName() + "不存在对应的set方法,无法参与拷贝!");
                  } catch (IllegalAccessException e) {
                      log.warn("【目标对象】异常:" + field.getName() + "的set方法执行失败!");
                  } catch (InvocationTargetException e) {
                      log.warn("【目标对象】异常:" + field.getName() + "的set方法执行失败!");
                  }
              }
              //设置目标类属性
              settingTargetField(propertyDescriptor, targetBean, originFieldKeyWithValueMap, beanClass.getSuperclass());
          }
      }

       

  • 两个list比较

    • 先把list不比较的参数设置为空

      • //调用处    
        //不参与比较的字段, 全部设置为想用字段
         String controlPass ="id,tradeDate,appSheetSerialNo,sysFrom,opType,controlPersionId";
        // controlList 需要处理的list
        dealListNoCompare(controlList, controlPass);
        
        
        //处理传入list字段调用set方法写入为"", 也可以调整
        
        private void dealListNoCompare(Object list, String pass) {
                List<Object> listObject = (List<Object>) list;
                for (Object object : listObject) {
                    this.dealNoCompare(pass, object);
                }
            }
        
            private void dealNoCompare(String pass, Object object) {
                PropertyDescriptor propertyDescriptor;
                Field[] originFieldList = object.getClass().getDeclaredFields();
                String[] split = pass.split(",");
                for (Field field : originFieldList) {
                    try {
                        for (int i = 0; i < split.length; i++) {
                            String[] fields = field.toString().split("\\.");
                            if (fields[fields.length - 1].equals(split[i])) {
                                propertyDescriptor = new PropertyDescriptor(field.getName(), object.getClass());
                                //设置值
                                Method method = propertyDescriptor.getWriteMethod();
                                method.invoke(object, "");
                            }
                        }
                    } catch (Exception e) {
                        log.error("处理不参加比较方法失败:" + e);
                        System.out.println(e);
                    }
                }
            }
        
        

         

    • 比较两个list是否相同

      • //比较两个list是否相同
            public static boolean isListEqual(List l0, List l1) {
                if (l0 == l1)
                    return true;
                if (l0 == null && l1 == null)
                    return true;
                if (l0 == null || l1 == null)
                    return false;
                if (l0.size() != l1.size())
                    return false;
                for (Object o : l0) {
                    if (!l1.contains(o))
                        return false;
                }
                for (Object o : l1) {
                    if (!l0.contains(o))
                        return false;
                }
                return true;
            }

         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值