Java 流短路操作:我们可以假设一个一个的处理吗?

Java stream short circuiting operations: Can we assume one by one processing?

提问人:Lord M-Cube 提问时间:10/10/2022 更新时间:10/10/2022 访问量:103

问:

关于短路操作的 JavaDoc 规范只讨论无限和有限流以及这些流的终止。

但我想知道我们是否可以安全地假设这些元素将以“一个接一个”的方式进行处理,或者换句话说:我们是否可以假设不仅有短路,而且即使是获得结果所需的最少处理?

例如:

Object first = list.stream().map(expensiveMappingFunction).findFirst().orElse(null);

现在很高兴知道我是否可以确定只处理一个元素,因为映射函数可能需要每个元素很长时间(或者我真的只想调用一次的任何其他原因)。否则我会选择旧的 -check 和 .empty()iterator().next()

JavaDoc 似乎没有具体说明这一点,所以也许我们不能假设这一点。

但也许有某种像这样的“非官方惯例”。

或者,也许我只是对 Java 流的理解还不够,这是一个愚蠢的问题(在这种情况下,您可能会很乐意指出它!

java-stream 短路

评论

4赞 Rogue 10/10/2022
在您的示例中,它将是一个顺序流,其中元素被 1 逐个处理(从直到到达终端操作)。此保证在并行流中使用 .在保证“最少的必要处理”方面 - 流将被处理,直到满足其终端操作指定的条件。因此,在找到第一个结果时将终止流。无法从本质上保证流将是最佳解决方案。#stream#findFirstStream#parallel#findFirst
0赞 Lord M-Cube 10/11/2022
@Rogue我应该提到“顺序”流,因为“并行”流对我来说是一个完全不同的世界。我只是问,因为一个人可能会实现一个终端操作,该操作需要 - 比方说 - 3 批(无论出于何种原因)。就像 ArrayList 具有任意初始容量(有充分的理由)一样,可能会有一次占用多个元素的终端操作。我问的是,是否可能存在这种情况。
0赞 Rogue 10/11/2022
在顺序流中,没有“一次接受 1 个以上元素”的终端操作。在并行流的上下文中,无论哪种方式都可以争论这一点 - 一些收集器将收集“批量”处理的数据并在最终确定结果之前合并它们。然而,支撑这些收集器的实际操作仍然是流元素到其最终容器的 1 对 1 操作(即它们仍将一个接一个地处理)。
1赞 Holger 10/11/2022
没有这样的保证。但是,也不能保证 JVM 实现者不会在每个语句后插入过时的 counting-to-100 万循环。你必须相信他们和你有相同的目标,尽可能高效地实施事情,而不是无缘无故地做某事。也许,未来的版本将使用矢量化一次处理多个元素,但是,肯定会考虑此类更改不得引入不必要的昂贵中间步骤评估。另请参阅 en.wikipedia.org/wiki/Principle_of_least_astonishment
0赞 Brian Schack 11/7/2022
在您的示例中,您可以在 findFirst 之后应用 expensiveMappingFunction: Object first = list.stream().findFirst().map(expensiveMappingFunction).orElse(null);

答: 暂无答案