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.
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.