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.