I'm neither an expert in streams nor an everyday user. So take this with a grain of salt.
What you seem to want has nothing to do with happens-before. Happens-before is about memory model. What you want is a guarantee that iterate() will not be called after it has produced null, because doing so would mean your idiom is buggy. I think you have that guarantee. iterate() produces a sequential ordered stream. takeWhile() is an intermediate operation, and it does not change whether the stream is parallel or sequential. Unless you insert parallel() between these two calls, a terminal operation will not cause iterate() to produce more than one null element because streams are lazy. Put differently, you should never see a NullPointerException thrown from your snippet. That's my understanding. FWIW, there's a fused overload of iterate() that additionally takes the termination condition that your snippet passes to takeWhile(). It will behave correctly and similarly to your snippet even if the stream is later parallelized. On Sun, Mar 1, 2026 at 5:29 AM Jige Yu <[email protected]> wrote: > > Hi @core-libs-dev, > > I am looking to validate the following idiom: > > Stream.iterate(seed, e -> e.nextOrNull()) > .takeWhile(Objects::nonNull); > > The intent is for the stream to call nextOrNull() repeatedly until it returns > null. However, I am concerned about where the Stream specification guarantees > the correctness of this approach regarding happens-before relationships. > > The iterate() Javadoc defines happens-before for the function passed to it, > stating that the action of applying f for one element happens-before the > action of applying it for subsequent elements. However, it seems silent on > the happens-before relationship with downstream operations like takeWhile(). > > My concern stems from the general discouragement of side effects in stream > operations. For example, relying on side effects between subsequent map() > calls is considered brittle because a stream might invoke the first map() on > multiple elements before the second map() processes the first element. > > If this theory holds, is there anything theoretically preventing iterate() > from generating multiple elements before takeWhile() evaluates the first one? > I may be overthinking this, but I would appreciate your insights into why > side effects are discouraged even in ordered, sequential streams and whether > this specific idiom is safe. > > Appreciate your help! > > Best regards, > Jige Yu
