Search code examples
javajsonjacksonjackson-databind

How to create mentioned specific JSON format


This is the JSON format which I am getting through the API.

Currently generated JSON format

[
  {
    "question":"q1",
    "option":"a"
  },
  {
    "question":"q1",
    "option":"b"
  },
  {
    "question":"q1",
    "option":"c"
  },
  {
    "question":"q1",
    "option":"d"
  },
  {
    "question":"q2",
    "option":"a"
  },
  {
    "question":"q2",
    "option":"b"
  }
]

After receiving and converting the above json formar, I want to send the below json format. but I am facing issue to creating below mentioned json format. suppose the list contains above JSON format then what I have tried is:

List finalList = new ArrayList();
list.stream.forEach(k - > {
    List optionList = new ArrayList();
    Map m = new HashMap();
    if (!m.containsKey(k.getQuestion)) {
        m.put("ques", k.getQuestion());
    }
    optionList.add(k.getOption());
    m.put("option", optionList);
    finalList.add(m);
})
System.out.println(finalList);

but above code is not returning specific prefered JSON format.

JSON format which I want to generate

[
  {
    "question":"q1",
    "option":[
      "a",
      "b",
      "c",
      "d"
    ]
  },
  {
    "question":"q2",
    "option":[
      "a",
      "b"
    ]
  }
]

Solution

    1. You can create java pojos for both JSON structures. pojo for source structure:
    class SourceData {
        private String question;
        private String option;
        // getters and setters
    }
    
    1. Target JSON pojo:
    class TargetData {
        private String question;
        private List<String> options;
        // getters and setters
    }
    
    1. Serialize source json to pojos
    List<SourceData> sourceDatas = new ObjectMapper().readValue(jsonString, new TypeReference<List<SourceData>>() {});
    
    1. Traverse through source pojo objects and transform to target pojos
    List<TargetData> targetDatas = new ArrayList<>();
    
    sourceDatas.stream().collect(Collectors.groupingBy(item -> item.getQuestion()))
        .forEach((question, itemList) -> {
            TargetData targetData = new TargetData();
            targetData.setQuestion(question);
            List<String> options = itemList.stream().map(SourceData::getOption).collect(Collectors.toList());
            targetData.setOptions(options);
            targetDatas.add(targetData);
        });