BiFunction - apply 方法应该总是返回第二个参数。为什么?

我正在尝试从其前身大于其价值的列表中识别数字。


在 lambda 表达式中,如果我返回 b,它的行为符合预期,但如果我返回 a,它会给出错误的输出。


这两个 return 语句有什么区别?


    List<Integer> list = Arrays.asList(1,2,3,4,5,8,7);

    List<Integer> result = new ArrayList<>();

    list.stream().reduce((a,b) -> {if (a < b) result.add(a);return b;});

    System.out.println(result);


    result.clear();

    list.stream().reduce((a,b) -> {if (a < b) result.add(a);return a;});

    System.out.println(result);

输出:


[1, 2, 3, 4, 5]


[1, 1, 1, 1, 1, 1]


子衿沉夜
浏览 94回答 2
2回答

白衣非少年

您正在执行的减少 - 使用Optional<T> java.util.stream.Stream.reduce(BinaryOperator<T> accumulator)- 等效于以下伪代码(取自 Javadoc):boolean foundAny = false;T result = null;for (T element : this stream) {&nbsp; &nbsp; if (!foundAny) {&nbsp; &nbsp; &nbsp; &nbsp; foundAny = true;&nbsp; &nbsp; &nbsp; &nbsp; result = element;&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; result = accumulator.apply(result, element);&nbsp; &nbsp; }}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(因为它保留第一个元素并忽略所有其他元素)。

动漫人物

这不是您问题的直接答案,但由于我说有状态过滤器会更好,所以我觉得有必要展示它。采用以下有状态谓词:public class GreaterThanPreceding implements Predicate<Integer> {&nbsp; &nbsp; private Integer preceding = null;&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean test(Integer current) {&nbsp; &nbsp; &nbsp; &nbsp; boolean greaterThan = preceding == null || (current > preceding);&nbsp; &nbsp; &nbsp; &nbsp; preceding = current;&nbsp; &nbsp; &nbsp; &nbsp; return greaterThan;&nbsp; &nbsp; }}这样,流操作将如下所示:List<Integer> collected = list.stream()&nbsp; &nbsp; &nbsp; &nbsp; .filter(new GreaterThanPreceding())&nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toList());System.out.println(collected);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java