Add convenience collect methods to the Stream interface

Peter Levart peter.levart at
Tue Dec 11 13:42:51 UTC 2018

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) {

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()) {

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