[英]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.