Java 将HashMap转换为包含列表属性的对象
是否可以将此HashMap转换为相应的对象?可能使用Jackson对象映射器、Gson甚至Mapstruct。这里的技巧是如何映射列表属性,在我的输入中,属性名称中有一个数字作为后缀: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", &
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"
} ]
}