我想知道Iterable
接口(interface)为什么不提供stream()
和parallelStream()
方法。考虑以下类别:
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();
}
}
它是一手牌的一种实现,因为您在玩交易纸牌游戏时可以手拿牌。
本质上,它包装了
List<Card>
,确保最大容量并提供了一些其他有用的功能。最好直接将其实现为List<Card>
。现在,为了方便起见,我认为实现
Iterable<Card>
会很好,这样,如果要遍历它,可以使用增强的for循环。 (我的Hand
类还提供了get(int index)
方法,因此,我认为Iterable<Card>
是合理的。)Iterable
接口(interface)提供以下内容(省略了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);
}
}
现在您可以通过以下方式获取流:
Stream<Hand> stream = StreamSupport.stream(hand.spliterator(), false);
因此,真正的问题是:
Iterable<T>
不提供实现stream()
和parallelStream()
的默认方法,我看不出有什么方法可以做到这一点? 我发现的一个相关问题如下:Why does Stream<T> not implement Iterable<T>?
奇怪的是,这暗示它可以反过来做。
最佳答案
这不是遗漏; 2013年6月,对EG列表进行了详细讨论。
专家组的确切讨论源于this thread。
尽管stream()
在Iterable
上似乎是“显而易见的”(甚至在专家组中也是如此),但Iterable
如此笼统的事实成为一个问题,因为明显的签名:
Stream<T> stream()
并非总是您想要的。例如,有些是
Iterable<Integer>
的东西宁愿让其stream方法返回IntStream
。但是将stream()
方法放在层次结构中的较高位置将使这成为不可能。因此,相反,通过提供Stream
方法,使从Iterable
生成spliterator()
变得非常容易。 stream()
中Collection
的实现只是:default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
任何客户端都可以通过以下方式从
Iterable
获取所需的流:Stream s = StreamSupport.stream(iter.spliterator(), false);
最后,我们得出结论,将
stream()
添加到Iterable
将是一个错误。