obesechicken13
obesechicken13

Reputation: 833

How would you do multiple operations on a java 8 stream?

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));

Upvotes: 17

Views: 26776

Answers (4)

Marvin Richter
Marvin Richter

Reputation: 621

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;
}

Upvotes: 14

Steve Storck
Steve Storck

Reputation: 991

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

Upvotes: 2

rathna
rathna

Reputation: 1083

personList.forEach(person ->   
   {
     personJson.put("firstName",person.firstName);
     personJson.put("lastName", person.lastName);
  });

Upvotes: 3

Karthik Bharadwaj
Karthik Bharadwaj

Reputation: 444

 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);
        });

Upvotes: 13

Related Questions