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);
添加回答
举报