297

Java 8 にはクラスStream<T>があり、不思議なことにメソッドがあります

Iterator<T> iterator()

したがって、まさにこのメソッドを必要とするインターフェイスIterable<T>を実装することを期待するでしょうが、そうではありません。

foreach ループを使用して Stream を反復処理する場合は、次のようにする必要があります

public static Iterable<T> getIterable(Stream<T> s) {
    return new Iterable<T> {
        @Override
        public Iterator<T> iterator() {
            return s.iterator();
        }
    };
}

for (T element : getIterable(s)) { ... }

ここで何か不足していますか?

4

9 に答える 9

221

人々はすでにメーリングリストで同じことを尋ねています☺. 主な理由は、Iterable には再反復可能なセマンティックもありますが、Stream にはありません。

Iterable主な理由は再利用性を意味することだと思いますが、Streamは一度しか使用できないものですIterator

Stream拡張された場合、既存のコードは、2 回目にをスローするIterableを受け取ったときに驚くかもしれません。IterableExceptionfor (element : iterable)

于 2013-11-21T19:26:45.983 に答える
176

を に変換するStreamにはIterable、次のようにします。

Stream<X> stream = null;
Iterable<X> iterable = stream::iterator

Streamを期待するメソッドに aを渡すにはIterable

void foo(Iterable<X> iterable)

単に

foo(stream::iterator) 

ただし、おそらくおかしく見えます。もう少しはっきりしたほうがいいかもしれません

foo( (Iterable<X>)stream::iterator );
于 2013-11-21T19:46:29.087 に答える
7

kennytm はStream、 aを として扱うのが安全でない理由を説明しIterableZhong Yu は、危険な方法ではあるが as を as として使用できる回避策を提供しStreamましたIterable。両方の世界を最大限に活用することが可能です:仕様によって行われるすべての保証を満たす再利用可能なIterableから。StreamIterable

注:SomeTypeここでは型パラメーターではありません。適切な型 (例: ) に置き換えるか、Stringリフレクションに頼る必要があります。

Stream<SomeType> stream = ...;
Iterable<SomeType> iterable = stream.collect(toList()):

大きな欠点が 1 つあります。

遅延反復の利点は失われます。現在のスレッドですべての値をすぐに反復処理することを計画している場合、オーバーヘッドは無視できます。ただし、部分的または別のスレッドでのみ反復することを計画した場合、この即時の完全な反復が意図しない結果をもたらす可能性があります。

もちろん、大きな利点は を再利用できることですがIterable、これは 1 回しか使用できません(Iterable<SomeType>) stream::iterator。受信側のコードがコレクションを複数回反復する場合、これは必要であるだけでなく、パフォーマンスに有益である可能性があります。

于 2016-01-22T08:15:08.213 に答える
0

完璧ではありませんが、動作します:

iterable = stream.collect(Collectors.toList());

ストリームからすべてのアイテムを取得してそこに入れるため、完璧ではありListません。彼らは怠け者であるはずです。IterableStream

于 2017-01-07T04:47:48.620 に答える