populate a List<Object1> based on another List<Object2> using java 8 stream

akapti :

I have 2 List
List<Obligation> and List<ObligationStatus> Structure is as follows:

public class Obligation {
    private String topic;
    private String status;
    private String comment;
    private String text;
}

and

public class ObligationStatus {

    private String topic;
    private String status;
    private String comment;
}

status and comment inside List<Obligation> is null for all the elements,
topic is populated in both the list
I want to set the status and comment from each element of List<ObligationStatus> into each element of List<Obligation> based on topic.

        // this is what i have tried, and is working fine
        obList.stream().forEach(ob -> {
            osList.stream().forEach(os -> {
                if (ob.getTopic().equalsIgnoreCase(os.getTopic())) {
                    ob.setStatus(os.getStatus());
                    ob.setComment(os.getComment());
                }
            });
        });
// also tried to do this without using forEach, but compilation error here
        List<Obligation> result = obList.stream()
                .map(ob -> osList.stream().map(os -> os.getTopic().equals(ob.getTopic())).collect(Function.identity()))
                .collect(Collectors.toList());

Can we do this without suing forEach ?
any info would be helpful.

Andreas :

Why use stream for this? Stream is not the right tool for mutating objects.

Use standard for loops. Makes code easier to understand too.

List<Obligation> obligationList = ...;
List<ObligationStatus> statusList = ...;

// For better performance, make a map
Map<String, ObligationStatus> statusMap = new HashMap<>(statusList.size());
for (ObligationStatus status : statusList)
    statusMap.put(status.getTopic(), status);

// Assign status values
for (Obligation obligation : obligationList) {
    ObligationStatus status = statusMap.get(obligation.getTopic());
    if (status != null) {
        ob.setStatus(status.getStatus());
        ob.setComment(status.getComment());
    }
}

If you want to do some stream logic, the first part is a good candidate:

// For better performance, make a map
Map<String, ObligationStatus> statusMap = statusList.stream()
        .collect(Collectors.toMap(ObligationStatus::getTopic, Function.identity()));

UPDATE

Noticed that question code did equalsIgnoreCase(...) when comparing topic values. If that is really needed, change the HashMap to a case-insensitive TreeMap:

Map<String, ObligationStatus> statusMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

The stream version of that gets convoluted, so better keep it old-style.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=127417&siteId=1