Add convenience collect methods to the Stream interface

Remi Forax forax at
Tue Dec 11 14:24:10 UTC 2018

And i've forgotten to add that currently calling stream.iterator() is sloooow,
i don't know if it's just because the implementation of this method did not get some love or it's a more fundamental issue because a spliterator is push while an iterator is pull so the implementation needs an intermediary memory to store the element in between.


----- Mail original -----
> De: "Remi Forax" <forax at>
> À: "Peter Levart" <peter.levart at>
> Cc: "Rob Griffin, rgriffin" <Rob.Griffin at>, "core-libs-dev" <core-libs-dev at>
> Envoyé: Mardi 11 Décembre 2018 15:18:24
> Objet: Re: Add convenience collect methods to the Stream interface

> Hi Rob, Hi Petter,
> we (the lambda EG) have decided against implementing Iterable (see the answer of
> Brian), so for consistency we have also not enable the right hand side of a
> enhanced for loop to be a poly-expression (that enables the lambda conversion),
> hence the mandatory cast.
> Rémi
> ----- Mail original -----
>> De: "Peter Levart" <peter.levart at>
>> À: "Rob Griffin, rgriffin" <Rob.Griffin at>, "Remi Forax"
>> <forax at>
>> Cc: "core-libs-dev" <core-libs-dev at>
>> Envoyé: Mardi 11 Décembre 2018 14:42:51
>> Objet: Re: Add convenience collect methods to the Stream interface
>> Hi Rob,
>> On 12/10/18 11:11 PM, Rob Griffin (rgriffin) wrote:
>>> Hi Remi,
>>> There are certainly places where we could do this when we are simply iterating
>>> over the results but that is not always the case. However I was disappointed to
>>> find that the enhanced for loop can't iterate over a stream so if callers of
>>> your example methods where doing something like this
>>> for (Employee emp : getAllEmployee()) {
>>>    ...
>>> }
>>> then it would have to change to a forEach call if getAllEmployee returned a
>>> Stream.
>> You can also get an Iterator from a Stream, so if you need external
>> iteration over elements of a Stream you don't have to collect it 1st to
>> some Collection:
>>     Stream<String> names() {
>>         return Stream.of("John", "Jil", "Jack");
>>     }
>> ...and then...
>>         for (String name : (Iterable<String>) names()::iterator) {
>>             System.out.println(name);
>>         }
>> This is hack-ish as it relies on the fact that enhanced for loop calls
>> Iterable.iterator() method only once, but is the only way to do it if
>> you already have a reference to Stream at hand. This would be more
>> correct way of doing it if you can call a factory for Stream:
>>         for (String name : (Iterable<String>) () -> names().iterator()) {
>>             System.out.println(name);
>>         }
>> Regards, Peter
>> P.S. I wonder why the enhanced for loop doesn't establish a context
>> where the type of expression after the colon could be inferred, so no
>> cast would be necessary. Perhaps because that type could either be an
> > Iterable<T> or a T[] ?

More information about the core-libs-dev mailing list