为什么Iterable<T>不提供 stream() 和 parallelStream() 方法?
我想知道为什么 Iterable
接口不提供 stream()
和 parallelStream()
方法.考虑以下类:
public class Hand 实现 Iterable{私人最终名单<卡>list = new ArrayList<>();私有最终 int 容量;//...@覆盖公共迭代器<卡>迭代器(){返回 list.iterator();}}
它是Hand的一种实现,因为您可以在玩集换式卡牌游戏时手中有牌.
本质上它包装了一个List
,确保最大容量并提供一些其他有用的功能.最好将其直接实现为 List<Card>
.
现在,为了方便起见,我认为实现 Iterable<Card>
会很好,这样如果你想循环它,你可以使用增强的 for 循环.(我的 Hand
类还提供了一个 get(int index)
方法,因此我认为 Iterable
是合理的.)p>
Iterable
接口提供以下内容(省略 javadoc):
公共接口Iterable<T>{迭代器<T>迭代器();默认 void forEach(Consumer super T> action) {Objects.requireNonNull(action);对于 (T t : 这个) {action.accept(t);}}默认拆分器<T>分裂器(){return Spliterators.spliteratorUnknownSize(iterator(), 0);}}
现在你可以获得一个流:
流<手>流 = StreamSupport.stream(hand.spliterator(), false);
所以到真正的问题:
- 为什么
Iterable<T>
不提供实现stream()
和parallelStream()
的默认方法,我看不出有什么让这变得不可能或不需要?
我发现的一个相关问题如下:为什么 Stream<T>不实现Iterable<T>?
奇怪的是,它暗示它以相反的方式去做.
这不是遗漏;2013年6月EG名单有详细讨论.
专家组的最终讨论植根于 this线程.
虽然看起来很明显"(即使对专家组来说,最初也是如此)stream()
似乎对 Iterable
有意义,但事实上 Iterable
太笼统成了一个问题,因为明显的签名:
流<T>溪流()
并不总是你想要的.例如,一些 Iterable<Integer>
的东西宁愿让他们的流方法返回一个 IntStream
.但是将 stream()
方法放在层次结构的如此高处会使这成为不可能.因此,我们通过提供 spliterator()
方法,让从 Iterable
生成 Stream
变得非常容易.Collection
中stream()
的实现就是:
默认流<E>溪流() {返回 StreamSupport.stream(spliterator(), false);}
任何客户端都可以通过 Iterable
获取他们想要的流:
Stream s = StreamSupport.stream(iter.spliterator(), false);
最后我们得出结论,将 stream()
添加到 Iterable
是错误的.
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.
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.
相关文章