15

You have a list of a pojo you want to convert to a JSONObject for instance. You have a list of pojo. But in order to convert to a JSONObject you need to use the JSONObject put method.

JSONObject personJson = new JSONObject();
for(Person person : personList){
   personJson.put("firstName", person.firstName);
   personJson.put("lastName", person.lastname);
   ...
}

If it were just one operation I wanted to do, then I could do

personList.stream.map(personJson.put("firstName", person.firstName));
obesechicken13
  • 795
  • 1
  • 12
  • 24

4 Answers4

13
 JSONArray array=new JSONArray();
        personList.stream().forEach(element ->
        {
            JSONObject personJson = new JSONObject();
            personJson.put("firstName", element.firstName);
            personJson.put("lastName", element.lastname);
            array.add(personJson);
        });
12

The solutions mentioned here are working but they are mutating objects outside the streams context, which should be avoided.

So instead of using .forEach() which is a terminating operation returning void. The correct approach would be to use .map() which, like the name says, maps one value to another. In your case the first operation you want to do is to map a Person to a JSONObject. The second operation is a reducer function where you want to reduce all JSONObjects to one JSONArray object.

public JSONArray mapListToJsonArray(List<Person> persons) {
    List<JSONObject> jsonObjects = persons
            .stream()
            .map(person -> {
                JSONObject json = new JSONObject();
                json.put("firstName", person.getFirstName());
                json.put("lastName", person.getLastName());
                return json;
            })
            .collect(Collectors.toList());
    return new JSONArray(jsonObjects);
}

Unfortunately the json.org implementation of JSONArray does not have a way to easily merge two arrays. So I instead of reducing to a JSONArray, I first collected all JSONObjects as a List and created a JSONArray from that.

The solution looks even nicer if you replace the lambda expression with a method reference.

public JSONArray mapListToJsonArray(List<Person> persons) {
    List<JSONObject> jsonObjects = persons
            .stream()
            .map(this::mapPersonToJsonObject)
            .collect(Collectors.toList());
    return new JSONArray(jsonObjects);
}

public JSONObject mapPersonToJsonObject(Person person) {
    JSONObject json = new JSONObject();
    json.put("firstName", person.getFirstName());
    json.put("lastName", person.getLastName());
    return json;
}
Marvin Richter
  • 591
  • 6
  • 11
3
personList.forEach(person ->   
   {
     personJson.put("firstName",person.firstName);
     personJson.put("lastName", person.lastName);
  });
rathna
  • 1,055
  • 2
  • 11
  • 23
  • 3
    Welcome to Stack Overflow! While you may have solved this user's problem, code-only answers are not very helpful to users who come to this question in the future. Please edit your answer to explain why your code solves the original problem. – Joe C Feb 21 '17 at 07:09
2

The explanation by @rathna is correct. When you find yourself typing collection.stream().forEach(), you should collapse this to collection.forEach().

taras
  • 6,566
  • 10
  • 39
  • 50
Steve Storck
  • 793
  • 6
  • 25