简体   繁体   中英

Create an Object instance from a Map

I have a map with keys and string values.
This Map has been built reading a resource bundle where the data is organised in the following way:

height=160
weight=80
name=bob

And I have a class Person which has the fields: height, weight and name.

class Person{
 int height;
 int weight;
 String name;
 //..getter and setter..
}

I would like to create an instance of the class Person from the Map: height:160, weight:80, name:bob The best would be a generic solution, or something that uses some utilities.

Do you have any idea? how can I do that in Java? or using the framework Spring?

Have a look at the Spring BeanWrapper interface and its implementations if you'd like to use something from Spring. You can use it to wrap your bean and dynamically populate your bean from a map like this:

    Map<String, String> properties = new HashMap<>();
    properties.put("height", "160");
    properties.put("weight", "80");
    properties.put("name", "bob");

    BeanWrapper person = new BeanWrapperImpl(new Person());
    for (Map.Entry<String, String> property : properties.entrySet()) {
        person.setPropertyValue(property.getKey(), property.getValue());
    }

    System.out.println(person.getWrappedInstance().toString());

This will print:

    -> Person [height=160, weight=80, name=bob]

The classic Java way is to pass the value Map as an argument to the constructor of Person and let person read the properties from the map.

This way you can have multiple ways for constructing a Person object. Either by passing arguments directly, or passing the map.

I would like to bring forward another benefit of this approach. If you do it this way, the cohesion is very high. This means that the knowledge of how to construct a Person object from a Map of values is coded within the class itself. If you would do this outside of the class and you want to construct Person objects in different locations of you program, then you would need to replicate the code for getting values from the map or abstract it into a utility method. Now you don't, and if you every would need to change the way how to construct a Person object you simply change it in one place.

import java.util.Map;

public class Person {

  private static final String WEIGHT_PROPERTY = "weight";
  private static final String HEIGHT_PROPERTY = "height";

  private final int height;
  private final int weight;

  public Person(Map<String, String> map){
    height = Integer.parseInt(map.get(HEIGHT_PROPERTY));
    weight = Integer.parseInt(map.get(WEIGHT_PROPERTY));
  }

  public int getHeight() {
    return height;
  }

  public int getWeight() {
    return weight;
  }

}

Simplifying @Jeroen Peeters post

    public class Person {
       Map<String, String> prop;

       public Person(Map<String, String> map){
          prop = map
       }

       public int getHeight() {
           return Integer.parseInt(prop.get("height"))
       }

       public int getWeight() {
          return Integer.parseInt(prop.get("weight"));
       }
    }
Map<String, String> map = ...;
int height = Integer.parseInt(map.get("height"));
int weight = Integer.parseInt(map.get("weight"));
Person p = new Person(height, weight);

Note that ResourceBundle is normally used to deal with internationalization. If you just need to read properties, then use the java.util.Properties class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM