1. ホーム

[解決済み】Iterable<T>がstream()とparallelStream()メソッドを提供しないのはなぜですか?

2022-04-04 04:02:51

質問

なぜ 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();
    }
}

を実装したものです。 ハンド トレーディングカードゲームで遊ぶときに手札を持つことができるように。

基本的には List<Card> で、最大容量を確保し、他のいくつかの便利な機能を提供します。この機能は、直接 List<Card> .

さて、便利なように、私は実装するのがいいと思いました Iterable<Card> ループさせたい場合は、拡張for-loopを使用することができます。(私の Hand クラスはまた get(int index) メソッドで、そのため Iterable<Card> は正当化されると私は思います)。

は、その 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> を実装したデフォルトのメソッドを提供しません。 stream()parallelStream() このようなことが不可能になる、あるいは不要になるようなことはないのでしょうか?

関連する質問として、次のようなものを見つけましたが。 なぜ Stream<T> は Iterable<T> を実装していないのですか?

それは奇妙なことに、それを多少なりとも逆に行うことを示唆している。

解決方法は?

これは漏れではなく、2013年6月にEGリストで詳細な議論が行われました。

に、専門家集団の決定的な議論が根付いています。 このスレッド .

というのは、(当初、専門家グループにとっても)自明なことのように思われました。 stream() には意味があるように思えました。 Iterable というのは Iterable があまりにも一般的であることが問題になりました。なぜなら、明白な署名があるからです。

Stream<T> stream()

は、必ずしも思い通りになるとは限りませんでした。というものもありました。 Iterable<Integer> は、むしろそのストリームメソッドが 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 は間違いだと思います。