如何在JAVA中对jsonObject的值求和,并在jsonArray中创建sum的新jsonObject?

如何在JAVA中对jsonObject的值求和,并在jsonArray中创建sum的新jsonObject?,java,arrays,json,vert.x,Java,Arrays,Json,Vert.x,我有如下的JSON数组,希望对JSON对象的值求和,并在JSON数组中创建sum的新JSON对象: { "client":[ { "member":12, "group":"g1" }, { "member":17, "group":"g2" } ], "client2":[ { "member":14, "gr

我有如下的JSON数组,希望对JSON对象的值求和,并在JSON数组中创建sum的新JSON对象:

{
   "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);
      }
    });
mainJson.fieldNames().forEach(fn->{
JsonArray JsonArray=mainJson.getJsonArray(fn);
int id=0;
for(int i=0;i
因此,下面是一个使用库(谷歌json解析器)的完整示例

首先,我创建了用于定义初始json文件的类:

import java.io.Serializable;
import java.util.ArrayList;

public class ClientSer implements Serializable {
    ArrayList<ClientDataSer> client;
    ArrayList<ClientDataSer> client2;

    public ClientSer(ArrayList<ClientDataSer> client, ArrayList<ClientDataSer> client2) {
        this.client = client;
        this.client2 = client2;
    }

    public ArrayList<ClientDataSer> getClient() {
        return client;
    }

    public void setClient(ArrayList<ClientDataSer> client) {
        this.client = client;
    }

    public ArrayList<ClientDataSer> getClient2() {
        return client2;
    }

    public void setClient2(ArrayList<ClientDataSer> client2) {
        this.client2 = client2;
    }
}
为了让gson使用文件作为数据结构的定义,它们需要是可序列化的。稍后我将了解为什么ClientDataSer扩展ClientDataParentSer

读取此文件、计算总成员值并将其打印到另一个文件的代码如下所示:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.*;
import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {


        Gson gson = new GsonBuilder()
                .setPrettyPrinting()
                .create();

        try (Reader reader = new FileReader("test.json")) {

            // Convert JSON File to Java Object
            ClientSer clientSer = gson.fromJson(reader, ClientSer.class);

            ClientNewSer clientNewSer = new ClientNewSer(getNewClientData(clientSer.getClient()), getNewClientData(clientSer.getClient2()));

            try {
                Writer writer = new FileWriter("testNew.json");
                gson.toJson(clientNewSer, writer);
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static ArrayList<ClientDataParentSer> getNewClientData(ArrayList<ClientDataSer> clientDataSerList) {

        ArrayList<ClientDataParentSer> clientDataSers = new ArrayList<>();

        int memberCounter = 0;
        for (ClientDataParentSer clientDataSer : clientDataSerList) {

            clientDataSers.add(clientDataSer);

            memberCounter += ((ClientDataSer)clientDataSer).getMember();
        }

        ClientDataNewSer clientDataNewSer = new ClientDataNewSer("all", memberCounter);

        clientDataSers.add(clientDataNewSer);

        return clientDataSers;

    }
}
import java.io.Serializable;
import java.util.ArrayList;

public class ClientNewSer implements Serializable {
    ArrayList<ClientDataParentSer> client;
    ArrayList<ClientDataParentSer> client2;

    public ClientNewSer(ArrayList<ClientDataParentSer> client, ArrayList<ClientDataParentSer> client2) {
        this.client = client;
        this.client2 = client2;
    }

    public ArrayList<ClientDataParentSer> getClient() {
        return client;
    }

    public void setClient(ArrayList<ClientDataParentSer> client) {
        this.client = client;
    }

    public ArrayList<ClientDataParentSer> getClient2() {
        return client2;
    }

    public void setClient2(ArrayList<ClientDataParentSer> client2) {
        this.client2 = client2;
    }
}
然后创建ClientDataSer和一个新类:

public class ClientDataNewSer extends ClientDataParentSer {

    int member;

    public ClientDataNewSer(String group, int member) {
        super(group);
        this.member = member;
    }

    public int getMember() {
        return member;
    }

    public void setMember(int member) {
        this.member = member;
    }
}
扩展这个父类,我们可以有一个包含这两者的ClientDataParentSer列表,即输出json文件所需的列表

新对象的类如下所示:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.*;
import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {


        Gson gson = new GsonBuilder()
                .setPrettyPrinting()
                .create();

        try (Reader reader = new FileReader("test.json")) {

            // Convert JSON File to Java Object
            ClientSer clientSer = gson.fromJson(reader, ClientSer.class);

            ClientNewSer clientNewSer = new ClientNewSer(getNewClientData(clientSer.getClient()), getNewClientData(clientSer.getClient2()));

            try {
                Writer writer = new FileWriter("testNew.json");
                gson.toJson(clientNewSer, writer);
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static ArrayList<ClientDataParentSer> getNewClientData(ArrayList<ClientDataSer> clientDataSerList) {

        ArrayList<ClientDataParentSer> clientDataSers = new ArrayList<>();

        int memberCounter = 0;
        for (ClientDataParentSer clientDataSer : clientDataSerList) {

            clientDataSers.add(clientDataSer);

            memberCounter += ((ClientDataSer)clientDataSer).getMember();
        }

        ClientDataNewSer clientDataNewSer = new ClientDataNewSer("all", memberCounter);

        clientDataSers.add(clientDataNewSer);

        return clientDataSers;

    }
}
import java.io.Serializable;
import java.util.ArrayList;

public class ClientNewSer implements Serializable {
    ArrayList<ClientDataParentSer> client;
    ArrayList<ClientDataParentSer> client2;

    public ClientNewSer(ArrayList<ClientDataParentSer> client, ArrayList<ClientDataParentSer> client2) {
        this.client = client;
        this.client2 = client2;
    }

    public ArrayList<ClientDataParentSer> getClient() {
        return client;
    }

    public void setClient(ArrayList<ClientDataParentSer> client) {
        this.client = client;
    }

    public ArrayList<ClientDataParentSer> getClient2() {
        return client2;
    }

    public void setClient2(ArrayList<ClientDataParentSer> client2) {
        this.client2 = client2;
    }
}
import java.io.Serializable;
导入java.util.ArrayList;
公共类ClientNewSer实现了可序列化{
ArrayList客户端;
ArrayList客户端2;
PublicClientNewser(ArrayList客户端,ArrayList客户端2){
this.client=client;
this.client2=client2;
}
公共ArrayList getClient(){
返回客户;
}
public void setClient(ArrayList客户端){
this.client=client;
}
公共阵列列表getClient2(){
返回客户2;
}
public void setClient2(ArrayList client2){
this.client2=client2;
}
}
任何关于以下评论的问题


完整项目位于my github上,您期望的JSON字符串不正常,因为属于同一JSON数组的任何JSON对象都应该具有相同的结构,因此输出JSON字符串应该如下所示:

{
  "client":[
    {
      "member":12,
      "group":"g1"
    },
    {
      "member":17,
      "group":"g2"
    },
    {
      "member":29,
      "group":"all"
    }
  ],
  ...
}
如果您期望的JSON字符串可以这样修改,那么下面是另一种实现所需的方法,方法是使用
Jackson
Lambda Expression
(自Java 8以来):

步骤1
创建POJO并使用
@JsonAnySetter
客户端
客户端2
序列化为
列表
,使用
@JsonIgnore
进行
getName()
反序列化以忽略字段
名称

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
}
控制台输出:

RootPojo[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[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{
if(clientMap.containsKey(e.getName())){
get(e.getName()).add(e);
}否则{
List clients=new ArrayList();
添加(e);
put(例如getName(),clientMap.put);
}
});
字符串outputJsonStr=mapper.writeValueAsString(clientMap);
System.out.println(outputJsonStr);
控制台输出:

{“客户”:[{“成员”:12,“集团”:“g1”},{“成员”:17,“集团”:“g2”},{“成员”:29,“集团”:“所有”},““客户2”:[{“成员”:14,“集团”:“g11”},{“成员”:175,“集团”:“g22”},{“成员”:189,“集团”:“所有”}


请添加您的尝试。我已添加我的尝试。拜托,有人能帮我吗@NinaScholzI不认为您期望的JSON字符串是好的,因为属于同一JSON数组的任何JSON对象都应该具有相同的体系结构。不用担心。如果你真的打算使用Gson,我建议如果你能控制它的话,制作一个更好的数据结构。比如制作一个客户列表,而不是2个字段client和client2。
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());
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);