Paul Sandoz paul.sandoz at
Fri Nov 23 03:21:56 PST 2012


There has been some discussions on the confusion of reusing streams when iterating and evaluating in addition to non-linear streams (where a two or more child streams share the same parent stream).

e.g. iteration:

Stream s1 = ..
Stream s2 =;
Iterator i1 = s1.iterator();
Iterator i2 = s2.iterator();

e.g. evaluation:

Stream s1 = ..
Stream s2 =;
Object i1 = s1.findFirst();
Object i2 = s2.findFirst();

e.g. non-linear

Stream p = ..
Stream c1 =;
Stream c2 = p.filter(...);

There are many cases that will produce unexpected or confusing results when iterating or evaluating (and in the case of parallel evaluation it is trickier). So we made a hasty retreat to the strict position of no-reuse-streams:

- Only one terminal operation may be performed.
An IllegalStateException is thrown on subsequent terminal operations.

- Stream.iterator() is a terminal operation (as will be spliterator() when added).

- A parent stream may only have one child stream.
An IllegalStateException is thrown if a child stream is created from a parent that already has a child.

In all of the above examples the last line will result in an ISE being thrown.


Should the following throw an ISE on the last line of the following?

Stream s = ..
Object i1 = s.findFirst();
Stream s1 =;

i.e. should we fail on the or just when a terminal operation occurs, if at all?


More information about the lambda-libs-spec-experts mailing list