Java.lang.Iterable<T>
を返すインターフェースがあります。
その結果をJava 8 Stream APIを使用して操作したいと思います。
しかしIterableは「ストリーミング」できません。
どのようにそれをListに変換せずにIterableをStreamとして使用するかについての任意のアイデア?
spliteratorUnknownSize
を直接使用するよりもはるかに良い答えがあります。これはどちらもより簡単でより良い結果を得ます。 Iterable
はspliterator()
メソッドを持っているので、あなたはあなたのspliteratorを得るためにそれを使うべきです。最悪の場合、それは同じコードです(デフォルトの実装はspliteratorUnknownSize
を使用します)が、あなたのIterable
がすでにコレクションであるもっと一般的なケースでは、あなたはより良いspliterator、そしてより良いストリームパフォーマンスを得ます)コードも少なくなります。
StreamSupport.stream(iterable.spliterator(), false)
.filter(...)
.moreStreamOps(...);
ご覧のとおり、Iterable
からストリームを取得すること( この質問 も参照)はそれほど苦痛ではありません。
バージョン21以降、Guavaライブラリを使用できる場合は、次のものを使用できます。
Streams.stream(iterable)
Stream
またはIterable
からIterator
を簡単に作成できます。
public static <T> Stream<T> stream(Iterable<T> iterable) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
iterable.iterator(),
Spliterator.ORDERED
),
false
);
}
_ jool _ libraryを使用することをお勧めします。これはSeq.seq(iterable)呼び出しの背後にあるspliteratorの魔法を隠し、さらに便利な機能をたくさん提供します。
私はこのクラスを作成しました:
public class Streams {
/**
* Converts Iterable to stream
*/
public static <T> Stream<T> streamOf(final Iterable<T> iterable) {
return toStream(iterable, false);
}
/**
* Converts Iterable to parallel stream
*/
public static <T> Stream<T> parallelStreamOf(final Iterable<T> iterable) {
return toStream(iterable, true);
}
private static <T> Stream<T> toStream(final Iterable<T> iterable, final boolean isParallel) {
return StreamSupport.stream(iterable.spliterator(), isParallel);
}
}
あなたはspliteratorsとbooleans(isParallel)について考える必要がないので、私はそれが完全に読みやすいと思います。
この問題に対する非常に簡単な回避策は、default <T> stream()
メソッドを保持するStreamable<T>
を拡張するIterable<T>
インターフェースを作成することです。
interface Streamable<T> extends Iterable<T> {
default Stream<T> stream() {
return StreamSupport.stream(spliterator(), false);
}
}
Iterable<T>
の代わりにimplements Streamable<T>
を宣言するだけで、どんなIterable<T>
も簡単にストリーミングできるようになります。
別の答えが述べたように、グアバはこれをサポートしています:
Streams.stream(iterable);
私は、実装は他の答えが提案したものとは少し違うことをしていることを強調したい。 Iterable
がCollection
型の場合、それらはそれをキャストします。
public static <T> Stream<T> stream(Iterable<T> iterable) {
return (iterable instanceof Collection)
? ((Collection<T>) iterable).stream()
: StreamSupport.stream(iterable.spliterator(), false);
}
public static <T> Stream<T> stream(Iterator<T> iterator) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(iterator, 0),
false
);
}
たまたまVavr(以前のJavaslangとして知られている)を使用するなら、これは同じくらい簡単でありえます:
Iterable i = //...
Stream.ofAll(i);