Why does Stream<T> not implement Iterable<T>?
In Java 8 we have the class Stream<T>, which curiously have a method
Iterator<T> iterator()
So you would expect it to implement interface Iterable<T>, which requires exactly this method, but that's not the case.
When I want to iterate over a Stream using a foreach loop, I have to do something like
public static Iterable<T> getIterable(Stream<T> s) {
return new Iterable<T> {
@Override
public Iterator<T> iterator() {
return s.iterator();
}
};
}
for (T element : getIterable(s)) { ... }
Am I missing something here?
Solution 1:
People have already asked the same on the mailing list ☺. The main reason is Iterable also has a re-iterable semantic, while Stream is not.
I think the main reason is that
Iterable
implies reusability, whereasStream
is something that can only be used once — more like anIterator
.If
Stream
extendedIterable
then existing code might be surprised when it receives anIterable
that throws anException
the second time they dofor (element : iterable)
.
Solution 2:
To convert a Stream
to an Iterable
, you can do
Stream<X> stream = null;
Iterable<X> iterable = stream::iterator
To pass a Stream
to a method that expects Iterable
,
void foo(Iterable<X> iterable)
simply
foo(stream::iterator)
however it probably looks funny; it might be better to be a little bit more explicit
foo( (Iterable<X>)stream::iterator );