Lambda – iterates over two lists using a Java 8 stream

How do I write the following in a Java 8 stream?

int total = 0;
  for (ObjectA obja : rootObj.getListA()) {
    for (ObjectB objb : obja.getListB()) {
        total += objb.getCount() * obja.getCount();
    }
   }

return total;

Solution

The canonical solution for converting nested for loops to stream API usage is through flatmap:

return rootObj.getListA().stream()
.flatMapToInt(objA->objA.getListB().stream()
                                   .mapToInt(objB->objB.getCount() * objA.getCount()))
.sum();

This allows you to perform operations for each internal iteration However, in the special case of summation, you can simplify the operation because it doesn't matter whether you calculate (a B C D) or (a b) (c d):

return rootObj.getListA().stream()
.mapToInt(objA->objA.getListB().stream()
                               .mapToInt(objB->objB.getCount() * objA.getCount()).sum())
.sum();

When we remember the basic arithmetic, we should also remember that (a * x) (b * x) is equal to (AB) * X. in other words, it is not necessary to match each item of listb with obja, because we can also double the result of this count:

return rootObj.getListA().stream()
.mapToInt(objA->objA.getListB().stream().mapToInt(ObjectB::getCount).sum()*objA.getCount())
.sum();
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>