paul.sandoz at oracle.com
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).
Stream s1 = ..
Stream s2 = s1.map(...);
Iterator i1 = s1.iterator();
Iterator i2 = s2.iterator();
Stream s1 = ..
Stream s2 = s.map(...);
Object i1 = s1.findFirst();
Object i2 = s2.findFirst();
Stream p = ..
Stream c1 = p.map(...);
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 = s.map(...);
i.e. should we fail on the s.map(...) or just when a terminal operation occurs, if at all?
More information about the lambda-libs-spec-experts