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. Rémi ----- Mail original -----
De: "Remi Forax" <forax@univ-mlv.fr> À: "Peter Levart" <peter.levart@gmail.com> Cc: "Rob Griffin, rgriffin" <Rob.Griffin@quest.com>, "core-libs-dev" <core-libs-dev@openjdk.java.net> 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@gmail.com> À: "Rob Griffin, rgriffin" <Rob.Griffin@quest.com>, "Remi Forax" <forax@univ-mlv.fr> Cc: "core-libs-dev" <core-libs-dev@openjdk.java.net> 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[] ?