Java Stream: difference between forEach and forEachOrdered

若如初见. 提交于 2019-12-06 05:06:56

The #3 code is not conceptually equivalent to #1, because parallel() or sequential() calls affect the whole stream, not just the subsequent operations. So in #3 case the whole procedure will be performed sequentially. Actually #3 case resembles the early design of the Stream API when you actually could change the parallel/sequential mode. This was considered to be unnecessary complication (and actually added problems, see, for example, this discussion) as usually you only need to change mode to make the terminal operation ordered (but not necessarily sequential). So forEachOrdered() was added and parallel()/sequential() semantics was changed to affect the whole stream (see this changeset).

Basically you're right: in parallel stream there's no order guarantee for intermediate operations. If you need to perform them in particular order, you have to use the sequential stream.

Holger

You are right in that the guarantees made for the action of forEachOrdered only apply to that action and nothing else. But it’s wrong to assume that this is the same as .sequential().forEach(…).

sequential will turn the entire stream pipeline into sequential mode, thus, the action passed to forEach will be executed by the same thread, but also the preceding peek’s action. For most intermediate operations, the exact placement of parallel or sequential is irrelevant and specifying both makes no sense as only the last one will be relevant.

Also, there is still no guaranty made about the ordering when using forEach, even if it hasn’t any consequences in the current implementation. This is discussed in “Does Stream.forEach respect the encounter order of sequential streams?”

The documentation of Stream.forEachOrdered states:

This operation processes the elements one at a time, in encounter order if one exists. Performing the action for one element happens-before performing the action for subsequent elements, but for any given element, the action may be performed in whatever thread the library chooses.

So the action may get invoked by different threads, as perceivable by Thread.currentThread() but not run concurrently. Further, if the stream has an encounter order, it will get reconstituted at this place. This answer sheds some light one the difference of encounter order and processing order.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!