java - 如何对 jsonObject 的值求和并在 JAVA 的 jsonArray 中创建 sum 的新 jsonobject?
问题描述
我有如下 JSON 数组,想要对 JSON 对象的值求和,并在 JSON 数组中创建新的 sum 对象:
{
"client":[
{
"member":12,
"group":"g1"
},
{
"member":17,
"group":"g2"
}
],
"client2":[
{
"member":14,
"group":"g11"
},
{
"member":175,
"group":"g22"
}
]
}
我想对 jsonarray 中每个 jsonobject 的成员值求和,并创建额外的 json 并将其放在客户端数组中。预期的 json 应如下所示:
{
"client":[
{
"member":12,
"group":"g1"
},
{
"member":17,
"group":"g2"
},
{
"totalMember":29,
"group":"all"
}
],
"client2":[
{
"member":14,
"group":"g11"
},
{
"member":175,
"group":"g22"
},
{
"totalMember":189,
"group":"all"
}
]
}
我试过:
mainJson.fieldNames().forEach(fn->{
JsonArray jsonArray = mainJson.getJsonArray(fn);
int id = 0;
for (int i = 0; i < jsonArray.size(); i++) {
id += jsonArray.getJsonObject(i).getInteger("id");
JsonObject jsonObject = new JsonObject().put("id",id).put("group","all");
jsonArray.add(jsonObject);
mainJson.put(fn,jsonArray);
}
});
解决方案
您预期的 JSON 字符串不正常,因为属于同一个 JSON 数组的任何 JSON 对象都应具有相同的结构,因此输出 JSON 字符串应如下所示:
{
"client":[
{
"member":12,
"group":"g1"
},
{
"member":17,
"group":"g2"
},
{
"member":29,
"group":"all"
}
],
...
}
如果您预期的 JSON 字符串可以这样修改,那么这里有另一种方法来实现您想要的,通过使用Jackson
and Lambda Expression
(从 Java 8 开始)的步骤:
步骤 1
创建 POJO 并使用@JsonAnySetter
to 序列化client
和client2
to List<ClientInfo>
,并使用@JsonIgnore
forgetName()
进行反序列化以忽略字段name
。
class RootPojo {
private List<ClientInfo> clients = new ArrayList<>();
@JsonAnySetter
public void setClients(String name, List<ClientInfo> client) {
client.forEach(e -> {
e.setName(name);
});
this.clients.addAll(client);
}
//general getter and toString
}
class ClientInfo {
private String name;
private int member;
private String group;
@JsonIgnore
public String getName() {
return name;
}
//general getters, setters and toString
}
步骤 2
将 JSON 字符串序列化为预定义的 POJO Jackson
:
ObjectMapper mapper = new ObjectMapper();
RootPojo rootPojo = mapper.readValue(inputJsonStr, RootPojo.class);
System.out.println(rootPojo.toString());
控制台输出:
RootPojo [clients=[ClientInfo [name=client, member=12, group=g1], ClientInfo [name=client, member=17, group=g2], ClientInfo [name=client2, member=14, group=g11], ClientInfo [name=client2, member=175, group=g22]]]
第 3 步
用于Lambda Expression
分组和求和,这也将结果作为新的 JSON 对象添加回原始 JSON 字符串。
rootPojo.getClients()
.stream()
.collect(Collectors.groupingBy(ClientInfo::getName,
Collectors.summingInt(ClientInfo::getMember)))
.forEach((k,v) -> {
ClientInfo clientInfo = new ClientInfo();
clientInfo.setName(k);
clientInfo.setGroup("all");
clientInfo.setMember(v);
rootPojo.getClients().add(clientInfo);
});
System.out.println(rootPojo.toString());
控制台输出:
RootPojo [clients=[ClientInfo [name=client, member=12, group=g1], ClientInfo [name=client, member=17, group=g2], ClientInfo [name=client2, member=14, group=g11], ClientInfo [name=client2, member=175, group=g22], ClientInfo [name=client, member=29, group=all], ClientInfo [name=client2, member=189, group=all]]]
步骤 4
转换rootPojo
成Map<String, List<ClientInfo>
然后反序列化它以输出 JSON 字符串:
Map<String, List<ClientInfo>> clientMap = new HashMap<>();
rootPojo.getClients().forEach(e -> {
if (clientMap.containsKey(e.getName())) {
clientMap.get(e.getName()).add(e);
} else {
List<ClientInfo> clients = new ArrayList<>();
clients.add(e);
clientMap.put(e.getName(), clients);
}
});
String outputJsonStr = mapper.writeValueAsString(clientMap);
System.out.println(outputJsonStr);
控制台输出:
{"client":[{"member":12,"group":"g1"},{"member":17,"group":"g2"},{"member":29,"group":"全部"}],"client2":[{"member":14,"group":"g11"},{"member":175,"group":"g22"},{"member":189,"组":"全部"}]}
推荐阅读
- sccm - Set-CMTaskSequenceDeployment 的问题
- python - colab中如何导入AdversarialModel、simple_gan、gan_targets
- python - 具有重复项的类的多标签编码
- c# - 刷新选项卡 WPF 中的信息
- wpf - 如何使用 Scroll 事件刷新 Slider 的位置?
- ios - 如何在 swift 中使用自定义 url 加载 webview
- android - java.io.EOFException: \n not found: size=0 content=...
- android - Android Jetpack 导航深层链接在 AndroidManifest 上生成效果不佳
- django - DRF:如何根据字段权限限制嵌套序列化程序中的字段?
- javascript - 如何在 Facebook 应用内浏览器中接收邮件?