如何在Java 8流中编写以下内容?
int total = 0;
for (ObjectA obja : rootObj.getListA()) {
for (ObjectB objb : obja.getListB()) {
total += objb.getCount() * obja.getCount();
}
}
return total;
答案 0 :(得分:4)
将嵌套for
循环转换为Stream
API使用的规范解决方案是flatMap
:
return rootObj.getListA().stream()
.flatMapToInt(objA->objA.getListB().stream()
.mapToInt(objB->objB.getCount() * objA.getCount()))
.sum();
这允许您为每个内部迭代执行操作。但是,在汇总的特殊情况下,您可以简化操作,因为无论您计算(a+b+c+d)
还是(a+b)+(c+d)
都无关紧要:
return rootObj.getListA().stream()
.mapToInt(objA->objA.getListB().stream()
.mapToInt(objB->objB.getCount() * objA.getCount()).sum())
.sum();
当我们记住基本的算术时,我们也应该记得(a*x)+(b*x)
等于(a+b)*x
,换句话说,没有必要将ListB
的每个项目与计数为objA
,因为我们也可以将该结果的总和加倍:
return rootObj.getListA().stream()
.mapToInt(objA->objA.getListB().stream().mapToInt(ObjectB::getCount).sum()*objA.getCount())
.sum();
答案 1 :(得分:3)
这是一种替代解决方案,在许多情况下可能更为可取:
name: 'person'
答案 2 :(得分:2)
相当容易:将ObjectA
映射到其ObjectB::getCount
所有乘以getCount()
的总和,然后简单地将IntStream
求和:
int total = rootObj.getListA().stream()
.mapToInt(obja -> obja.getCount() * obja.getListB().stream().mapToInt(ObjectB::getCount).sum())
.sum();
为了提高可读性,您可以引入私有帮助方法:
int total = rootObj.getListA().stream()
.mapToInt(this::calculate)
.sum();
使用辅助方法:
private int calculate(ObjectA obja) {
return obja.getListB().stream()
.mapToInt(ObjectB::getCount)
.sum() * obja.getCount();
}
答案 3 :(得分:2)
对于一次性走两个流的更一般的解决方案,这个不是很好但是它可以工作解决方案。
ssh