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:
Iterable<T>
not provide a default methods that implement stream()
and parallelStream()
, 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.
The Iterable interface is designed keeping generality in mind and does not provide any stream() method on its own. Simply put, you can pass it to StreamSupport. stream() method and get a Stream from the given Iterable instance.
To perform the filtering process, filter() applies function to every item of iterable in a loop. The result is an iterator that yields the values of iterable for which function returns a true value. The process doesn't modify the original input iterable.
public final class StreamSupport extends Object. Low-level utility methods for creating and manipulating streams. This class is mostly for library writers presenting stream views of data structures; most static stream methods intended for end users are in the various Stream classes.
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 on Iterable
, the fact that Iterable
was so general became a problem, because the obvious signature:
Stream<T> stream()
was not always what you were going to want. Some things that were Iterable<Integer>
would rather have their stream method return an IntStream
, for example. But putting the stream()
method this high up in the hierarchy would make that impossible. So instead, we made it really easy to make a Stream
from an Iterable
, by providing a spliterator()
method. The implementation of stream()
in Collection
is just:
default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); }
Any client can get the stream they want from an Iterable
with:
Stream s = StreamSupport.stream(iter.spliterator(), false);
In the end we concluded that adding stream()
to Iterable
would be a mistake.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With