RFR: 8072727 - add variation of Stream.iterate() that's finite

Stefan Zobel spliterator at gmail.com
Sun Feb 14 18:15:59 UTC 2016

Hi Tagir,

this looks good. I wonder, however, if the signature should
accept a wider range of types, i.e., something like

static <T, S extends T> Stream<T> iterate(S seed, Predicate<S>
predicate, UnaryOperator<S> f)

I know that the corresponding

static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)

is less general than that, but I don't know whether this is
the outcome of a thoughtful decision or just an oversight.

What do you think?


2016-02-14 15:53 GMT+01:00 Tagir F. Valeev <amaembo at gmail.com>:
> Hello!
> I wanted to work on foldLeft, but Brian asked me to take this issue
> instead. So here's webrev:
> http://cr.openjdk.java.net/~tvaleev/webrev/8072727/r1/
> I don't like iterator-based Stream source implementations, so I made
> them AbstractSpliterator-based. I also implemented manually
> forEachRemaining as, I believe, this improves the performance in
> non-short-circuiting cases.
> I also decided to keep two flags (started and finished) to track the
> state. Currently existing implementation of infinite iterate() does
> not use started flag, but instead reads one element ahead for
> primitive streams. This seems wrong to me and may even lead to
> unexpected exceptions (*). I could get rid of "started" flag for
> Stream.iterate() using Streams.NONE, but this would make object
> implementation different from primitive implementations. It would also
> be possible to keep single three-state variable (byte or int,
> NOT_STARTED, STARTED, FINISHED), but I doubt that this would improve
> the performance or footprint. Having two flags looks more readable to
> me.
> Currently existing two-arg iterate methods can now be expressed as a
> partial case of the new method:
> public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
>     return iterate(seed, x -> true, f);
> }
> (same for primitive streams). I may do this if you think it's
> reasonable.
> I created new test class and added new iterate sources to existing
> data providers.
> Please review and sponsor!
> With best regards,
> Tagir Valeev.
> (*) Consider the following code:
> int[] data = {1,2,3,4,-1};
> IntStream.iterate(0, x -> data[x])
>          .takeWhile(x -> x >= 0)
>          .forEach(System.out::println);
> Currently this unexpectedly throws an AIOOBE, because
> IntStream.iterate unnecessarily tries to read one element ahead.

More information about the core-libs-dev mailing list