Does Stream.forEach respect the encounter order of sequential streams?

Specifications exist to describe the minimal guarantees a caller can depend on, not to describe what the implementation does. This gap is crucial, as it allows the implementation flexibility to evolve. (Specification is declarative; implementation is imperative.) Overspecification is just as bad as underspecification.

When a specification says “does not preserve property X”, it does not mean that the property X may never be observed; it means the implementation is not obligated to preserve it. Your claimed implication that encounter order is never preserved is simply a wrong conclusion. (HashSet doesn’t promise that iterating its elements preserves the order they were inserted, but that doesn’t mean this can’t accidentally happen — you just can’t count on it.)

Similarly, your implication of “that suggests forEach is intended to preserve order for sequential streams” because you saw an implementation that does so in some case is equally incorrect.

In both cases, it seems like you’re just uncomfortable with the fact that the specification gives forEach a great deal of freedom. Specifically, it has the freedom to not preserve encounter order for sequential streams, even though that’s what the implementation currently does, and further that it’s kind of hard to imagine an implementation going out of its way to process sequential sources out of order. But that’s what the spec says, and that’s what it was intended to say.

That said, the wording of the comment about parallel streams is potentially confusing, because it is still possible to misinterpret it. The intent of calling out the parallel case explicitly here was pedagogical; the spec is still perfectly clear with that sentence removed entirely. However, to a reader who is unaware of parallelism, it would be almost impossible to not assume that forEach would preserve encounter order, so this sentence was added to help clarify the motivation. But, as you point out, the desire to treat the sequential case specially is still so powerful that it would be beneficial to clarify further.

Leave a Comment