【问题标题】:Create an Object instance from a Map从地图创建对象实例
【发布时间】:2013-12-15 21:34:25
【问题描述】:

我有一个包含键和字符串值的地图。
此地图已构建为读取资源包,其中数据按以下方式组织:

height=160
weight=80
name=bob

我有一个 Person 类,其中包含以下字段:身高、体重和姓名。

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

我想从 Map 创建一个 Person 类的实例:height:160, weight:80, name:bob 最好的解决方案是通用解决方案,或使用某些实用程序的解决方案。

你有什么想法吗?我怎么能在Java中做到这一点?还是使用 Spring 框架?

【问题讨论】:

    标签: java spring spring-mvc map bundle


    【解决方案1】:

    实现这一点的最简单方法是使用杰克逊的ObjectMapper 类。

    ObjectMapper mapper = new ObjectMapper();
    Map<String, Object> fields = ...;
    Person o = mapper.convertValue (fields, Person.class);
    

    【讨论】:

    • 你救了我。非常感谢:)
    【解决方案2】:

    简化@Jeroen Peeters 的帖子

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

    【讨论】:

    • 如果地图中不存在属性怎么办?您将推迟此异常,直到您调用 getter。否则,您将直接在实例化时获得异常。偏爱,但值得考虑的事情。
    • return prop.containsKey(key) ? prop.get(key) : null 这样的事情可能会解决。但实际上,您应该根据所涉及的设计处理异常
    【解决方案3】:

    如果您想使用 Spring 中的某些东西,请查看 Spring BeanWrapper 接口及其实现。您可以使用它来包装您的 bean 并从这样的地图动态填充您的 bean:

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

    这将打印:

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

    【讨论】:

      【解决方案4】:

      经典的Java方式是将值Map作为参数传递给Person的构造函数,让person从map中读取属性。

      通过这种方式,您可以有多种方式来构造 Person 对象。通过直接传递参数或传递映射。

      我想提出这种方法的另一个好处。如果你这样做,凝聚力非常高。这意味着如何从值的 Map 构造 Person 对象的知识是在类本身中编码的。如果您要在类之外执行此操作,并且希望在程序的不同位置构造 Person 对象,那么您需要复制代码以从映射中获取值或将其抽象为实用方法。现在你不需要了,如果你每个人都需要改变构造 Person 对象的方式,你只需在一个地方改变它。

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

      }

      【讨论】:

        【解决方案5】:
        Map<String, String> map = ...;
        int height = Integer.parseInt(map.get("height"));
        int weight = Integer.parseInt(map.get("weight"));
        Person p = new Person(height, weight);
        

        请注意,ResourceBundle 通常用于处理国际化。如果您只需要读取属性,请使用java.util.Properties 类。

        【讨论】:

        • 感谢 JB,但我还有一个字符串字段,我希望尽可能地通用,因为如果有人要修改类,我必须修改我的代码。跨度>
        • 让 Person 负责从地图中读取属性。所以你不单独维护那个逻辑,这可能吗? (见我的回答)。
        猜你喜欢
        • 2012-07-27
        • 1970-01-01
        • 2023-02-08
        • 2013-06-18
        • 1970-01-01
        • 2013-09-13
        • 2011-04-10
        • 2021-07-22
        • 1970-01-01
        相关资源
        最近更新 更多