Stream.forEach 是否遵守顺序流的遭遇顺序?
Stream.forEach
的 Javadoc 说(强调我的):
此操作的行为是显式非确定性的。对于并行流管道,此操作不保证遵循流的遭遇顺序,因为这样做会牺牲并行性的好处。对于任何给定的元素,可以在库选择的任何时间和任何线程中执行操作。如果操作访问共享状态,则它负责提供所需的同步。
Java 9 Early Access Javadoc 中也存在相同的文本。
第一句话(“显式非确定性”)表明(但没有明确说明)此方法不保留遭遇顺序。但是,下一个明确表示不保留顺序的句子以“对于并行流管道”为条件,如果无论并行度如何应用该句子,则该条件将是不必要的。这让我不确定 forEach 是否保留了顺序流的遭遇顺序。
这个答案指出了流库实现调用.sequential().forEach(downstream)的地方
。这表明 forEach 旨在保持顺序流的顺序,但也可能只是库中的一个错误。
为了安全起见,我已经在自己的代码中避免了这种歧义,但是今天我发现NetBeans IDE的“使用功能操作”编辑器提示将转换forEachOrdered
for (Foo foo : collection)
foo.bar();
到
collection.stream().forEach((foo) -> {
foo.bar();
});
如果 forEach 不保留遭遇顺序,则会引入一个错误。在针对 NetBeans 报告 bug 之前,我想知道该库在源代码的支持下实际保证了什么。
我正在寻找来自权威来源的答案。这可能是库实现中的明确评论,Java开发邮件列表上的讨论(Google没有为我找到任何东西,但也许我不知道这些神奇的词),或者库设计师的声明(我知道其中两个,Brian Goetz和Stuart Marks,活跃在Stack Overflow上)。(请不要用“只使用 forEachOrdered 代替”来回答 -- 我已经这样做了,但我想知道没有错误的代码是否错误。