簡體   English   中英

如何將 HashMap 轉換為具體類?

[英]How do I cast a HashMap to a concrete class?

我有一個類,我們稱之為 Fruit,我有一個 HashMap。 我希望能夠初始化 Fruit 的新實例,但設置為 HashMap 中的值。 例如:

Map<String, String> map = new HashMap<String, String>();
map.put("name", "Banana");
map.put("color", "Yellow");

然后我想像這樣初始化一個新的 Fruit 實例:

Fruit myFruit = new Fruit(map);

要么

Fruit myFruit = (Fruit)map;

通過迭代 Map,這在 Java 中是可能的嗎?

第二個是不可能的,因為HashMap不是Fruit 您可以通過提供一個接受Map<String, String>參數的構造函數來完成第一個操作。

public Fruit(Map<String, String> map) {
  this.name = map.get("name");
  this.color = map.get("color");
}

似乎您可以為此使用反射

Fruit f = new Fruit();
Class aClass = f.getClass();
for(Field field : aClass.getFields()){
  if(map.containsKey(field.getName())){
    field.set(f,map.get(field.getName()));
  }
}

我已經修復了 Anni 的解決方案,現在它支持繼承、靜態和最終字段。 順便說一下,我沒有檢查類型不匹配。

public static void populateBean(Object bean, Map<String, Object> properties) throws Exception {
    Class<?> clazz = bean.getClass();
    while(clazz != null) {
        for (Field field : clazz.getDeclaredFields()) {
            int modifiers = field.getModifiers();
            if (!Modifier.isStatic(modifier) && !Modifier.isFinal(modifier)) {
                if (map.containsKey(field.getName())) {
                    field.accessible(true);
                    field.set(bean, map.get(field.getName()));
                }
            }
        }
        clazz = clazz.getSuperclass();
    }
}

順便說一下, Apache BeanUtils DynaBeans 幾乎可以做你想做的事,據我所知它支持 Java Beans Introspection。

與其他解決方案相比,它可能會慢一點,但對於要求不高的目的,我的代碼對我來說效果很好(而且它非常簡單和干凈):

public class Utils {
    static Object parseHashMapToObject(HashMap map, Class cls) {
        GsonBuilder gsonBuilder = new GsonBuilder();
        Gson gson = gsonBuilder.create();
        String jsonString = gson.toJson(map);
        return gson.fromJson(jsonString, cls);
    }
}

Gson Github: https : //github.com/google/gson

有點舊但是:

import com.fasterxml.jackson.databind.ObjectMapper;
...
final ObjectMapper mapper = new ObjectMapper();
final Map myObjectMapped = new HashMap();
//fill map
final Class clazz = Class.forName(MyClassToBeConverted.class.getName());
final MyClassToBeConverted convertedObj = (MyClassToBeConverted) mapper.convertValue(myObjectMapped, clazz);
...

是的,這是可能的。 但是您必須為 Fruit 編寫一個構造函數,它知道如何從映射中提取值——以及哪些值。

public Fruit(Map params) {
    this.setColor(map.get("color"));
    this.setName(map.get("name"));
}

您將在構造函數中遍歷地圖並分配值。 如果有一個實際的庫來做這個(幾乎像一個 Bean),那么我從來沒有聽說過它。

將 HashMap 轉換為水果是不可能的。

第二個是不可能的,但您可以創建一個類,將 Map 作為構造函數參數。

class Fruit{

  private Map<String, String> fruitMap;

  Fruit(Map<String, String> map){

  }

}

假設map的鍵對應於Fruit類中的 setter 方法,您可以使用 Apache bean 的實用程序之一,如PropertyUtils

final Fruit f = new Fruit();
for(String key : map.keySet()) {
    PropertyUtils.setProperty(fruit, key, map.get(key));
}

對於非常復雜的情況,您可能需要查看Dozer 我們使用 Dozer 將非常大的地圖映射到非常大的對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM