2 回答

TA貢獻1155條經驗 獲得超0個贊
您正在執行的減少 - 使用Optional<T> java.util.stream.Stream.reduce(BinaryOperator<T> accumulator)- 等效于以下偽代碼(取自 Javadoc):
boolean foundAny = false;
T result = null;
for (T element : this stream) {
if (!foundAny) {
foundAny = true;
result = element;
} else {
result = accumulator.apply(result, element);
}
}
return foundAny ? Optional.of(result) : Optional.empty();
如您所見,歸約result的中間值作為累加器的第一個參數傳遞,當前element的Stream作為第二個參數傳遞。
因此,當您的 lambda 表達式返回第二個參數b(第一個片段)時,中間結果成為 的當前元素,您將在下一次迭代中將Stream其添加到。List
當您的 lambda 返回第一個參數a(第二個片段)時,中間結果保持不變(始終1是 的第一個元素Stream),并且您繼續將該值添加到List.
讓我們用實際數字來驗證一下:
result被初始化為 Stream 的第一個元素1。
然后,第一個片段調用accumulator.apply(1,2),添加1到List并返回2(這成為新的中間結果)。下一次迭代將添加2到List并返回3。等等...
第二個代碼片段調用accumulator.apply(1,2),添加1到List并返回 1(這仍然是新的中間結果)。下一次迭代將再次添加1并List再次返回1。等等...
總而言之,您的兩個累積函數具有不同的功能:
第一個結果是的最后一個元素Stream(因為它不斷丟棄當前結果并將其替換為當前元素)。
第二個結果是的第一個元素Stream(因為它保留第一個元素并忽略所有其他元素)。

TA貢獻1815條經驗 獲得超10個贊
這不是您問題的直接答案,但由于我說有狀態過濾器會更好,所以我覺得有必要展示它。采用以下有狀態謂詞:
public class GreaterThanPreceding implements Predicate<Integer> {
private Integer preceding = null;
@Override
public boolean test(Integer current) {
boolean greaterThan = preceding == null || (current > preceding);
preceding = current;
return greaterThan;
}
}
這樣,流操作將如下所示:
List<Integer> collected = list.stream()
.filter(new GreaterThanPreceding())
.collect(Collectors.toList());
System.out.println(collected);
添加回答
舉報