【问题标题】:Java, Convert instance of Class to HashMapJava,将类的实例转换为 HashMap
【发布时间】:2016-05-04 09:55:13
【问题描述】:

如果我有这样的课:

class MyObject {
    public int myInt;
    public String myString;
}

是否可以在不实现转换代码的情况下将此类的实例转换为HashMap?

MyObject obj = new MyObject();
obj.myInt = 1; obj.myString = "string";
HashMap<String, Object> hs = convert(obj);

hs.getInt("myInt"); // returns 1
hs.getString("myString"); // returns "string"

Java有提供那种解决方案,还是我需要自己实现convert

我的班级有 50 多个字段,为每个字段编写转换器并不是一个好主意。

【问题讨论】:

  • Hashmaps 有键和值(2 个东西),而不是 50 个字段。您能澄清一下您要在这里实现的目标吗?
  • 您还必须提供自定义的Map 实现,因为从Map 获取键值的有效方法是get(Object) 方法。没有什么像 getIntgetString 这样可以从 Map 返回不同的类型。最后,拥有它们没有任何意义,因为返回类型是由第二个泛型类型定义的。
  • @TimBiegeleisen 我想将我的对象的所有字段转换为 hashmap 的键和值。
  • @Mr.D 您能否为此详细说明一个用例,因为我看不到任何用例。调用一个简单的 getter 方法对我来说会更容易,特别是因为更改任何这些字段中的单个值会使以前生成的 Map 无效。
  • @KevinEsche 有些库只接受哈希映射

标签: java


【解决方案1】:

使用杰克逊库,这也是可能的

MyObject obj = new MyObject();
obj.myInt = 1;
obj.myString = "1";
ObjectMapper mapObject = new ObjectMapper();
Map < String, Object > mapObj = mapObject.convertValue(obj, Map.class);

【讨论】:

【解决方案2】:

您可以使用反射来实现此行为。您可以获取要转换的类的所有字段,以对这些字段进行映射迭代,并将每个字段的名称作为映射的键。这将导致从字符串到对象的映射。

Map<String, Object> myObjectAsDict = new HashMap<>();    
Field[] allFields = SomeClass.class.getDeclaredFields();
    for (Field field : allFields) {
        Class<?> targetType = field.getType();
        Object objectValue = targetType.newInstance();
        Object value = field.get(objectValue);
        myObjectAsDict.put(field.getName(), value);
    }
}

【讨论】:

【解决方案3】:

这样的事情就可以解决问题:

MyObject obj = new MyObject();
obj.myInt = 1; obj.myString = "string";
Map<String, Object> map = new HashMap<>();
// Use MyObject.class.getFields() instead of getDeclaredFields()
// If you are interested in public fields only
for (Field field : MyObject.class.getDeclaredFields()) {
    // Skip this if you intend to access to public fields only
    if (!field.isAccessible()) {
        field.setAccessible(true);
    }
    map.put(field.getName(), field.get(obj));
}
System.out.println(map);

输出:

{myString=string, myInt=1}

【讨论】:

    【解决方案4】:

    您可以考虑使用地图而不是类。

    或者让你的班级扩展一个地图,例如

    public class MyObject extends HashMap<String, Object> {
    
    }
    

    【讨论】:

      【解决方案5】:

      如果你不想使用反射,那么你可以使用我的技巧。希望这可能对某人有所帮助。

      假设你的班级看起来像这样。

      public class MyClass {
               private int id;
               private String name; 
      }
      

      现在覆盖该类中的 toString() 方法。在 Eclipse 中也有一个生成此方法的快捷方式。

      public class MyClass {
          private int id;
          private String name; 
      
          @Override
          public String toString() {
              StringBuilder builder = new StringBuilder();
              builder.append("MyClass [id=").append(id).append(", name=").append(name).append("]");
              return builder.toString();
          }
      
      }
      

      现在在这个类中编写一个方法,将你的对象转换为Map&lt;String,String&gt;

      public Map<String, String> asMap() {
              Map<String, String> map = new HashMap<String, String>();
              String stringRepresentation = this.toString();
              if (stringRepresentation == null || stringRepresentation.trim().equals("")) {
                  return map;
              }
              if (stringRepresentation.contains("[")) {
                  int index = stringRepresentation.indexOf("[");
                  stringRepresentation = stringRepresentation.substring(index + 1, stringRepresentation.length());
              }
              if (stringRepresentation.endsWith("]")) {
                  stringRepresentation = stringRepresentation.substring(0, stringRepresentation.length() - 1);
              }
              String[] commaSeprated = stringRepresentation.split(",");
              for (int i = 0; i < commaSeprated.length; i++) {
                  String keyEqualsValue = commaSeprated[i];
                  keyEqualsValue = keyEqualsValue.trim();
                  if (keyEqualsValue.equals("") || !keyEqualsValue.contains("=")) {
                      continue;
                  }
                  String[] keyValue = keyEqualsValue.split("=", 2);
                  if (keyValue.length > 1) {
                      map.put(keyValue[0].trim(), keyValue[1].trim());
                  }
      
              }
              return map;
          }
      

      现在,您可以在应用程序的任何位置调用此方法从 Object 中获取 HashMap。干杯

      【讨论】:

        猜你喜欢
        • 2015-06-16
        • 1970-01-01
        • 2012-07-14
        • 2015-05-29
        • 2010-10-30
        • 2015-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多