我想知道为什么Iterable接口不提供stream()andparallelStream()方法。考虑以下类:
Iterable
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(); } }
它是 手 牌的一种实现,因为您可以在玩集换式卡牌游戏时手中拿着牌。
本质上,它包装了 a List<Card>,确保了最大容量并提供了一些其他有用的功能。最好直接将其实现为List<Card>.
List<Card>
现在,为了方便起见,我认为实现它会很好Iterable<Card>,这样如果你想循环它,你可以使用增强的 for 循环。(我的Hand班级还提供了一种get(int index)方法,因此Iterable<Card>我认为这是合理的。)
Iterable<Card>
Hand
get(int index)
该Iterable接口提供以下内容(省略 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>
这不是遗漏;2013年6月对EG名单进行了详细讨论。
专家组的最终讨论植根于这个线程。
虽然在 上似乎“显而易见”(即使对专家组来说也是如此)stream()似乎是有道理的Iterable,但如此笼统的事实Iterable成为一个问题,因为明显的签名:
Stream<T> stream()
并不总是你想要的。例如,有些事情Iterable<Integer>宁愿让他们的流方法返回一个IntStream。但是把这个stream()方法放在这么高的层次结构中,这将是不可能的。因此,相反,我们通过提供一个方法让Stream从a 生成 a 变得非常容易。in的实现只是:Iterable``spliterator()``stream()``Collection
Iterable<Integer>
IntStream
Stream
Iterable``spliterator()``stream()``Collection
default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); }
任何客户端都可以通过以下方式获取他们想要的流Iterable:
Stream s = StreamSupport.stream(iter.spliterator(), false);
最后我们得出结论,添加stream()到Iterable将是一个错误。