Marcos Guimaraes
Marcos Guimaraes

Reputation: 1295

Iterate through 2 objects and 1 nested object in Java 8

I have the following structure:

class Object1 {
   String id;
   Integer total;
}
class Object2 {
   String id;
   List<Object3> list;
}
class Object3 {
   Integer total;
}

When Object1 and Object2 have the same id I need to update the total from Object1 by summing up the total from all the Object3 within the list inside Object2 and subtracting from Object1 total.

It works like this without Java 8:

for (Object1 object1 : list1) {
     for (Object2 object2 : list2) {
          if (object1.getId().equals(object2.getId())) {
              int total = 0;
              for (Object3 object3 : object2.getlist3()) {
                   total += object3.getTotal();
              }
              object1.setTotal(object1.getTotal() - total);
          }
     }
}

This is what I have so far using Java 8:

list1.forEach(object1 -> list2.stream()
     .filter(object2 ->object2.getId().equals(object1.getId()))

But I don't know how to proceed with the logic because I am not very familiar with Java 8.

Upvotes: 1

Views: 110

Answers (1)

Michael
Michael

Reputation: 44150

Try this. Explanations are inline as comments

list1.forEach(object1 -> 
    object1.setTotal(
        object1.getTotal() - list2.stream()
            .filter(object2 -> object1.getId().equals(object2.getId()))
            .flatMap(object2 -> object2.getList3().stream()) // Stream<Object2> to Stream<Object3>
            .mapToInt(Object3::getTotal)                     // get each total
            .sum()                                           // sum them
    )
);

It is worth noting that you are calling object1.setTotal multiple times if more than one ID matches, effectively overriding the previous result. You may say that this is fine, and that the lists are populated in a such a way that there will only be one matching ID. In which case, you should add a break statement after object1.setTotal. This will avoid iterating over the remaining elements in list2 unnecessarily. A similar performance enhancement in a stream would require a significant change to the above example.

Upvotes: 3

Related Questions