Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将HashMap转换为包含列表属性的对象_Java_Jackson_Hashmap_Gson_Mapstruct - Fatal编程技术网

Java 将HashMap转换为包含列表属性的对象

Java 将HashMap转换为包含列表属性的对象,java,jackson,hashmap,gson,mapstruct,Java,Jackson,Hashmap,Gson,Mapstruct,是否可以将此HashMap转换为相应的对象?可能使用Jackson对象映射器、Gson甚至Mapstruct。这里的技巧是如何映射列表属性,在我的输入中,属性名称中有一个数字作为后缀: Map<String, String> map = new HashMap<String, String>() {{ put("fooName", "foo name"); put("bars1.barName", &

是否可以将此HashMap转换为相应的对象?可能使用Jackson对象映射器、Gson甚至Mapstruct。这里的技巧是如何映射列表属性,在我的输入中,属性名称中有一个数字作为后缀:

Map<String, String> map = new HashMap<String, String>() {{
   put("fooName", "foo name");
   put("bars1.barName", "bar at position 0 name");
   put("bars1.barValue", "bar at position 0 value");
   put("bars2.barName", "bar at position 1 name");
   put("bars2.barValue", "bar at position 1 value");
}};
      
public class Foo {
    
    String fooName;
    List<Bar> bars;
// getters/setters    
}
    
public class Bar {
    
    String barName;
    String barValue;
// getters/setters
}
Map Map=newhashmap(){{
put(“foo name”、“foo name”);
放置(“bars1.barName”,“位置0处的bar名称”);
放置(“bars1.barValue”,“位置0处的bar值”);
放置(“bars2.barName”,“位置1处的bar名称”);
放置(“bars2.barValue”,“位置1处的bar值”);
}};
公开课Foo{
字符串名称;
列表栏;
//能手/二传手
}
公共类酒吧{
字符串名称;
字符串值;
//能手/二传手
}

PS:此输入来自外部API调用,我无法修改源。

您可以使用中间hashmap进行转换。尝试下面的示例转换器。 备注:您可能希望对Foo和Bar使用适当的构造函数,或者使用setter(为了简单起见,我使用了公共字段)。并且没有错误处理

static Foo convertMap(Map<String, String> map){
    Foo foo = new Foo();
    foo.fooName = map.remove("fooName");

    Map<String, Bar> barsMap = new HashMap<String, Bar>();

    for(String key : map.keySet()){
      String[] split = key.split("\\.");
      String name = split[0];
      String attribute = split[1];

      Bar bar = null;
      if(barsMap.containsKey(name)){
        bar = barsMap.get(name);
      }
      else{
        bar = new Bar();
        barsMap.put(name, bar);
      }

      switch(attribute){
        case "barName": bar.barName = map.get(key); break;
        case "barValue": bar.barValue = map.get(key); break;
        default: break;
      }
    }

    foo.bars = new ArrayList(barsMap.values());

    return foo;
  }
静态Foo转换映射(映射映射){
Foo-Foo=新的Foo();
foo.fooName=map.remove(“fooName”);
Map barsMap=newhashmap();
for(字符串键:map.keySet()){
String[]split=key.split(\\);
字符串名称=拆分[0];
字符串属性=拆分[1];
Bar=null;
if(条形图容器(名称)){
bar=barsMap.get(名称);
}
否则{
bar=新的bar();
barsMap.put(名称、栏);
}
开关(属性){
case“barName”:bar.barName=map.get(key);break;
案例“barValue”:bar.barValue=map.get(键);break;
默认:中断;
}
}
foo.bar=newArrayList(barsMap.values());
返回foo;
}

您可以使用
@JsonAnySetter
注释以及条形图实例:

public class Foo {

    String fooName;
    private Map<Integer, Bar> map = new TreeMap<>();

    // getters/setters    
    public String getFooName() {
        return fooName;
    }
    public void setFooName(String fooName) {
        this.fooName = fooName;
    }
    public List<Bar> getBars() {
        return map.values().stream().collect(Collectors.toList());
    }

    @JsonAnySetter
    public void bars(String key, String value) {
        String[] ids = key.split("\\.");
        if (ids[0].startsWith("bars")) {
            Integer barKey = Integer.parseInt(ids[0].substring("bars".length())) - 1;
            String field = ids[1];
            Bar bar = map.computeIfAbsent(barKey, k -> new Bar());
            if ("barName".equals(field)) {
                bar.setBarName(value);
            } else if ("barValue".equals(field)) {
                bar.setBarValue(value);
            }
            map.put(barKey, bar);               
        }  // else handle other properties
    }
}

谢谢,这就是我要找的。
ObjectMapper m = new ObjectMapper();

Map<String, String> map = new HashMap<String, String>() {{
    put("fooName", "foo name");
    put("bars1.barName", "bar at position 0 name");
    put("bars1.barValue", "bar at position 0 value");
    put("bars2.barName", "bar at position 1 name");
    put("bars2.barValue", "bar at position 1 value");
}};

String json = m.writerWithDefaultPrettyPrinter().writeValueAsString(map);

Foo foo = m.readValue(json, Foo.class);

System.out.println("reserialized = " + m.writerWithDefaultPrettyPrinter().writeValueAsString(foo));
reserialized = {
  "fooName" : "foo name",
  "bars" : [ {
    "barName" : "bar at position 0 name",
    "barValue" : "bar at position 0 value"
  }, {
    "barName" : "bar at position 1 name",
    "barValue" : "bar at position 1 value"
  } ]
}