首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Stream.sorted().forEach()是否按预期工作?

Stream.sorted().forEach()是否按预期工作?
EN

Stack Overflow用户
提问于 2017-12-31 20:35:16
回答 3查看 3.7K关注 0票数 4

在处理Java项目时,我遇到了如下代码:

代码语言:javascript
复制
someMap.keySet().stream().sorted().forEach(/* ... */);

这里的意图显然是要为地图中的每个键做一些事情,根据键的自然顺序,这似乎是在实践中发生的事情。但是,我不确定这种行为是否得到了保证。Stream#forEach的Javadoc说:

此操作的行为是显式不确定的。对于并行流管道,此操作并不保证尊重流的遭遇顺序,因为这样做将牺牲并行性的好处。对于任何给定的元素,操作可以在库选择的任何时间和线程中执行。

我知道,如果代码使用的是.parallelStream()而不是.stream(),那么它就不能保证工作正常,但是由于它使用的是顺序流( Javadoc没有提到这一点),我不确定。这是否保证始终正常工作,或者该代码是否需要使用.forEachOrdered()而不是.forEach()呢?

编辑:我认为这个问题并不是Java 8流中的forEach与forEachOrdered的重复,因为这个问题是在问“forEach和forEachOrdered之间的区别的一个例子是什么”,而公认的答案基本上是“并行流”。这个问题是关于顺序流的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-12-31 20:38:53

不能保证forEach终端操作将按相遇顺序处理元素,因此“显式不确定”。尽管在当前实现下,它应该按照流的遭遇顺序处理顺序流的元素。

forEachOrdered主要用于使用并行流并希望尊重流的遇到顺序(如果流具有定义的遭遇顺序)的情况。

在顺序流上使用forEachforEachOrdered会产生同样的效果,所以这是一个优先考虑的问题。

如前所述,在当前的实现中,我们知道forEach终端操作应该按照流的遭遇顺序处理顺序流的元素,但是由于它没有在java中声明,所以如果您真的关心迭代顺序,最好坐在围栏上使用forEachOrdered

票数 10
EN

Stack Overflow用户

发布于 2017-12-31 21:17:57

在当前的实现下,它是--但是文档非常清楚,不把它作为规则来指定。这种情况显然是可以改变的,但目前它并没有改变,即使是在这样做的时候:

代码语言:javascript
复制
Stream.of(5, 4, 3, 1)
      .unordered()
      .forEach(System.out::println);

即使您是有意打破订单,对于顺序流,数据并不是有意在内部--至少目前没有。

但是,您必须小心,不要依赖它,因为不同版本之间可能会发生变化,这里有一个例子

票数 4
EN

Stack Overflow用户

发布于 2018-01-01 04:15:06

这是否保证始终工作,或者该代码是否需要使用.forEachOrdered()而不是.forEach()才能正常工作?

不是的。它不一定总是能起作用。正如javadoc所说,forEach()方法可能不是确定性的。这意味着实现者有权更改当前确定性行为不同的情况。

如果您希望确保确定性,请使用javadoc显式保证的方法。在未来的版本中,不太可能故意破坏.forEachOrdered()中对订单保存的明确保证。

所以..。我要向应用程序的维护人员指出这个错误。我们不能预测它将来会破裂,但它当然可以。潜在的虫子就是虫子。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48045510

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档