开发者

How do I cast a HashMap to a concrete class?

I have a class, lets call it Fruit, and I have a HashMap. I want to be able to initialize a new instance of Fruit, but set to the values in HashMap. So for example:

Map<String, String> map = new HashMap<String, String>();
开发者_开发问答map.put("name", "Banana");
map.put("color", "Yellow");

Then I want to be initialize a new Fruit instance like so:

Fruit myFruit = new Fruit(map);

or

Fruit myFruit = (Fruit)map;

Is this possible in Java, by means of iterating the Map?


The second is not possible because a HashMap is not a Fruit. You could do the first by providing a constructor that takes a Map<String, String> argument.

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


It seems like you can use reflection for this

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()));
  }
}


Little old but:

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);
...


Yes, it's possible. But you'd have to write a constructor for Fruit that knows how to pull values -- and which values -- from the map.

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


I have fixed Anni's solution, now it supports inheritance, and static and final fields. By the way, I have not checked for type mismatches.

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();
    }
}

By the way Apache BeanUtils DynaBeans almost does what you want, as far as I remember it supports Java Beans Introspection.


Maybe it could be a little slower in comparison to other solutions, but for not demanding purposes, my code works very well for me (And it is very simple and clean):

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


You would traverse the map in your constructor and assign the values. If there's an actual library for doing this(almost like a Bean), then I've never heard of it.

Casting of a HashMap to a fruit wouldn't be possible.


The second is not possible but you can create a class that will take a Map as a constructor parameter.

class Fruit{

  private Map<String, String> fruitMap;

  Fruit(Map<String, String> map){

  }

}


Assuming the keys in map correspond to setter methods in the Fruit class, you could use one of Apache bean's utilities like PropertyUtils.

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


For very complicated cases of this you might want to take a look at Dozer. We use Dozer to map very large Maps to very large objects.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜