Proposal: JDK-8148917 Enhanced-For Statement Should Allow Streams

Peter Levart peter.levart at
Thu Mar 14 15:26:05 UTC 2019

Now that Brian put it so nicely, I'm convinced and I'd like to draw back 
and support this proposal as is...

On 3/14/19 3:50 PM, Stephen Colebourne wrote:
> On Thu, 14 Mar 2019 at 14:21, Brian Goetz <brian.goetz at> wrote:
>> There's a reason it took as long as it did for Stuart to come up with
>> this proposal; all the options were known for years, they all have
>> problems, and the net benefit is still relatively narrow, which means we
>> don't have a lot of budget before the cost-benefit becomes negative.  I
>> think the option proposed is the least-worst, and people still seem to
>> really want to be able to foreach over streams.
> The cost-benefit is definitely tight, but I think it is positive. As I
> said here [1] there is still a case for control abstractions in Java
> even when you have lambdas
> A new concern from me is that this change would allow Iterable and
> Stream to be used in foreach, but not Iterator. This seems like an
> odd/sharp conceptual edge.

To be precise: this change would not allow Iterable and Stream to be 
used in foreach. foreach does not change. It would still alow only 
Iterable (and arrays). The Stream would become an Iterable with this change.

> Why not make `Iterator` implement `IterableOnce`? The default method
> would obviously just return `this`.

This would conflate concepts to much. Iterator *is* an external 
iteration state while Iterable[Once] is a (one-shot) factory for 
Iterator. The specification for IterableOnce could not say that the 
second and subsequent invocations of iterator() method are to throw 
exception if Iterator interface extended IterableOnce (interfaces have 
no state to model this in the default method).

> It seems to me that if we are willing to countenance foreach over a
> one-shot Stream, it is inappropriate to deny foreach to a one-shot
> Iterator.

Again, this proposal does not do anything to foreach specification. It 
just makes Stream be Iterable. The concepts here are more to the point:

Iterable: factory for Iterator
Stream: one-shot factory for Spliterator
Stream extends IterableOnce: one-shot factory for Spliterator and 
one-shot factory for Iterator

I think this makes perfect sense.

Regards, Peter

More information about the core-libs-dev mailing list