我覺得從java.util.stream
包摘要Reduction operations款能回答這個問題。讓我引用在這裏最重要的部分:
在其更一般的形式,在類型<T>
產生<U>
類型的結果的元素減少操作需要三個參數:
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
在這裏,標識元素既是縮減的初始種子值,又是沒有輸入元素時的默認結果。累加器函數獲取部分結果和下一個元素,並生成新的部分結果。組合器功能將兩個部分結果組合以產生新的部分結果。 (組合器在並行減少中是必需的,其中輸入被分區,爲每個分區計算部分累積,然後將部分結果組合以產生最終結果。)更正式地,標識值必須是組合器功能。這意味着對於所有的u
,combiner.apply(identity, u)
等於u
。另外,組合器功能必須是關聯的,並且必須與累加器功能兼容:對於所有的u
和t
,combiner.apply(u, accumulator.apply(identity, t))
必須是equals()
到accumulator.apply(u, t)
。
三參數形式是兩個參數形式的泛化,將映射步驟合併到累加步驟中。使用更一般的形式,如下所示,我們可以重新澆鑄求和的權重的簡單的例子:
int sumOfWeights = widgets.stream()
.reduce(0,
(sum, b) -> sum + b.getWeight())
Integer::sum);
雖然明確的地圖,減少形式的可讀性,因此應通常是優選的。通過將映射和減少組合到一個函數中,可以優化大量工作的情況下提供了廣義形式。
換言之,據我明白了,三個參數的形式在兩種情況下是有用的:
- 當並行執行的事項。
- 當通過組合映射和累積步驟可以實現顯着的性能優化時。否則,可以使用更簡單和可讀的顯式映射縮減表單。
明確的形式在同一文檔前面提到的:
int sumOfWeights = widgets.parallelStream()
.filter(b -> b.getColor() == RED)
.mapToInt(b -> b.getWeight())
.sum();
那確實功能。並行性上有趣的想法 - 將嘗試... –
這似乎是它。插入「.parallel()」會導致返回1000000。 –
@Garth酷,迫不及待地嘗試一下自己! –