如何在Java 8流中編寫以下內容?使用Java 8流遍歷兩個列表
int total = 0;
for (ObjectA obja : rootObj.getListA()) {
for (ObjectB objb : obja.getListB()) {
total += objb.getCount() * obja.getCount();
}
}
return total;
如何在Java 8流中編寫以下內容?使用Java 8流遍歷兩個列表
int total = 0;
for (ObjectA obja : rootObj.getListA()) {
for (ObjectB objb : obja.getListB()) {
total += objb.getCount() * obja.getCount();
}
}
return total;
相當容易:地圖ObjectA
到的所有ObjectB::getCount
乘以自身的getCount()
,然後簡單地總結了IntStream
總和:
int total = rootObj.getListA().stream()
.mapToInt(obja -> obja.getCount() * obja.getListB().stream().mapToInt(ObjectB::getCount).sum())
.sum();
爲了提高可讀性,你可以引入一個私有helper方法:
int total = rootObj.getListA().stream()
.mapToInt(this::calculate)
.sum();
用輔助方法:
private int calculate(ObjectA obja) {
return obja.getListB().stream()
.mapToInt(ObjectB::getCount)
.sum() * obja.getCount();
}
下面是一個替代的解決方案,其可能在一些情況下是優選的:
int total = rootObj.getListA().stream()
.flatMapToInt(objA -> objA.getListB()
.stream().mapToInt(objB -> objB.getCount() * objA.getCount()))
.sum();
用於轉換嵌套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();
而對於更廣泛的解決方案一次走兩條流這是不是很好,但它的工作原理的解決方案。
public static <A, B, C> Stream<C> zip(
Stream<A> a,
Stream<B> b,
BiFunction<A, B, C> op) {
Iterator<A> i1 = a.iterator();
Iterator<B> i2 = b.iterator();
Iterable<C> i =() -> new Iterator<C>() {
@Override
public boolean hasNext() {
return i1.hasNext() && i2.hasNext();
}
@Override
public C next() {
return op.apply(i1.next(), i2.next());
}
};
// Not certain whether we can do this in parallel - probably not.
return StreamSupport.stream(i.spliterator(), false);
}
這不是OP想要的。您正在同步迭代兩個流,並且作者想要爲listA的每個值迭代listB列表的所有值。你的版本是「點積」,而OP想要一個「跨產品」。 –
@TagirValeev - 這是真的 - 但這個答案適用於問題標題*使用Java 8流*迭代兩個列表。 – OldCurmudgeon
使用mapToInt的flatMapToInt insdead有什麼區別? – jliakos
'mapToInt'將每個元素轉換爲另一個元素,而'flatMapToInt'則將單個元素轉換爲多個元素的序列。 –