I am wondering why the Iterable
interface does not provide the stream()
and parallelStream()
methods. Consider the following class:
public class Hand implements Iterable<Card> {
private final List<Card> list = new ArrayList<>();
private final int capacity;
//...
@Override
public Iterator<Card> iterator() {
return list.iterator();
}
}
It is an implementation of a Hand as you can have cards in your hand while playing a Trading Card Game.
Essentially it wraps a List<Card>
, ensures a maximum capacity and offers some other useful features. It is better as implementing it directly as a List<Card>
.
Now, for convienience I thought it would be nice to implement Iterable<Card>
, such that you can use enhanced for-loops if you want to loop over it. (My Hand
class also provides a get(int index)
method, hence the Iterable<Card>
is justified in my opinion.)
The Iterable
interface provides the following (left out javadoc):
public interface Iterable<T> {
Iterator<T> iterator();
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
Now can you obtain a stream with:
Stream<Hand> stream = StreamSupport.stream(hand.spliterator(), false);
So onto the real question:
- Why does
Iterable<T>
not provide a default methods that implementstream()
andparallelStream()
, I see nothing that would make this impossible or unwanted?
A related question I found is the following though: Why does Stream<T> not implement Iterable<T>?
Which is oddly enough suggesting it to do it somewhat the other way around.
Best Answer
This was not an omission; there was detailed discussion on the EG list in June of 2013.
The definitive discussion of the Expert Group is rooted at this thread.
While it seemed "obvious" (even to the Expert Group, initially) that
stream()
seemed to make sense onIterable
, the fact thatIterable
was so general became a problem, because the obvious signature:was not always what you were going to want. Some things that were
Iterable<Integer>
would rather have their stream method return anIntStream
, for example. But putting thestream()
method this high up in the hierarchy would make that impossible. So instead, we made it really easy to make aStream
from anIterable
, by providing aspliterator()
method. The implementation ofstream()
inCollection
is just:Any client can get the stream they want from an
Iterable
with:In the end we concluded that adding
stream()
toIterable
would be a mistake.