Bean 屬性拷貝 忽略大小寫

日常java開發過程中會涉及到Bean類型轉換過程,即從一個Bean通過屬性拷貝的方式生成另一個Bean

通常代碼如下:

        TargetBean target=new TargetBean();
        BeanUtils.copyProperties(param,target);

注:這裏我用的是org.springframework.beans.BeanUtils


但是這種方式,是屬性名完全相同的的情況下才能複製屬性

比如這種情況下 A 的屬性 dwMap 到 B的屬性 dwmap就無法複製。下面給出忽略大小寫轉換拷貝bean的寫法

採用下面這種方法,dwMap 成員和dwmap成員會被認爲是相同變量而發生屬性複製

/**
   * 忽略大小寫轉換bean類型
   *
   * @param obj 轉換的源對象
   * @param clz 目標對象
   * @return 轉換後的對象
   */
  public static <T> T transferObjectIgnoreCase(Object obj, Class clz) {
    T result = null;
    try {
      if (obj != null && !obj.equals("")) {
        result = (T) clz.newInstance();
        //獲取目標類的屬性集合
        Map<String, Field> destPropertyMap = new HashMap<>();
        for (Field curField : clz.getDeclaredFields()) {
          destPropertyMap.put(curField.getName().toLowerCase(), curField);
        }
        //拷貝屬性
        for (Field curField : obj.getClass().getDeclaredFields()) {
          Field targetField = destPropertyMap.get(curField.getName().toLowerCase());
          if (targetField != null) {
            targetField.setAccessible(true);
            curField.setAccessible(true);
            targetField.set(result, curField.get(obj));
          }
        }
      }
    } catch (Exception e1) {
      return null;
    }
    return result;
  }

使用示例如下

Result result = PropertyUtils.transferObject(param,Result.class);


代碼解析

我來解釋下代碼(<T>是函數模板,這我就不多說了,不知道要好好看看java基礎了,)

首先手機目標類的成員,並存到map

//獲取目標類的屬性集合
 Map<String, Field> destPropertyMap = new HashMap<>();
 for (Field curField : clz.getDeclaredFields()) 
   destPropertyMap.put(curField.getName().toLowerCase(), curField);

這種是用map保存目標類的所有屬性,方便與源參數的屬性進行比對,判斷是不是擁有可以拷貝的屬性。如果不用map的話,你可以能就要用兩層for循環進行循環比對了,這樣效率很低,比如這個bean有20個屬性,另一個bean有20個屬性的,最差情況下要進行400次比對。用map的比對最差的情況下就是20次


下面將源參數的屬性名轉換成小寫(toLowerCase)和目標類的屬性進行比對

//拷貝屬性
for (Field curField : obj.getClass().getDeclaredFields()) {
    Field targetField = destPropertyMap.get(curField.getName().toLowerCase());
    if (targetField != null) {
      targetField.setAccessible(true);
      curField.setAccessible(true);
      targetField.set(result, curField.get(obj));
    }
}

如果目標類中存在相同名稱屬性時,通過Field.set和Field的get方式進行屬性拷貝

這樣就完成了屬性拷貝的過程。

注:我這沒做類型轉換的,複製的屬性必須類型相同的,你可以自己擴展哦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章