配列からストリームを作成するにはどうすればよいですか?


133

現在、配列からストリームを作成する必要があるときはいつでも、

String[] array = {"x1", "x2"};
Arrays.asList(array).stream();

配列からストリームを作成する直接的な方法はありますか?

回答:


201

あなたはArrays.stream Egを使用することができます

Arrays.stream(array);

Stream.of@fgeで言及されているように使用することもできます。

public static<T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}

しかし、ノートがStream.of(intArray)返されますStream<int[]>、一方、Arrays.stream(intArr)戻りますIntStreamあなたがタイプの配列を渡す提供しますint[]。つまり、プリミティブタイプの簡単な説明では、2つの方法の違いを観察できます。

int[] arr = {1, 2};
Stream<int[]> arr1 = Stream.of(arr);

IntStream stream2 = Arrays.stream(arr); 

プリミティブ配列をArrays.streamに渡すと、次のコードが呼び出されます

public static IntStream stream(int[] array) {
    return stream(array, 0, array.length);
}

プリミティブ配列をStream.of次のコードに渡すと呼び出されます

 public static<T> Stream<T> of(T t) {
     return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
 }

したがって、異なる結果が得られます。

更新スチュアートマークスのコメントで述べたとおり、前者はSIZEDストリームを生成するのに対して後者はそうではないため、サブレンジオーバーロードのArrays.stream使用が推奨されStream.of(array).skip(n).limit(m)ます。その理由は、それがあるlimit(m)サイズはメートル以下であるmより、一方かどうか分かりませんArrays.streamから返された範囲のチェックを行い、ストリームの正確なサイズを知っているあなたは、ストリームの実装のためのソースコードを読むことができArrays.stream(array,start,end) 、ここで、ストリームの実装のためで返さ一方、Stream.of(array).skip().limit()IS このメソッド内。


9
Arrays.streamプリミティブ配列のすべてのオーバーロードのケースがあるので、この答えはより良いです。すなわちStream.of(new int[]{1,2,3})、あなたにaを与えるのStream<int[]>に対し、おそらくあなたが望むものをArrays.stream返すIntStreamでしょう。したがって、+ 1
user2336315 2015年

3
@Dimaそれは好みの問題だと思います。私はある意味でStream.ofあなたにいくつかの驚きを与えることができるということを意味します(Arrays.asListプリミティブ配列で呼び出すとき、人々はList<Integer>背中を期待するなど):-)
user2336315

3
Arrays.stream配列の範囲のストリーミングをサポートしていますが、サポートしてIntStream.ofいません。これとは対照的に、Stream.ofあなたがあればより良い選択であるしたいStream<int[]>サイズのを1...
ホルガー

4
@Dimaのサブレンジオーバーロードは、前者がSIZEDストリームを生成するのに対し、後者はそうではないため、Arrays.stream使用するよりも望ましいStream.of(array).skip(n).limit(m)です。その理由はlimit(m)、サイズがと等しいかmそれより小さいかがわからないのmに対し、Arrays.stream範囲チェックはストリームの正確なサイズを知っているからです。
Stuart Marks

6
結論づけこの小さなドラマを見に興味がある読者のために、Arrays.stream(array,start,end)返しStream、実装があるここを一方、Stream.of(array).skip().limit()戻ってStreamその実装内でこのメソッド
Stuart Marks

43

@ sol4meのソリューションの代替:

Stream.of(theArray)

このとの差のArrays.stream():それはないあなたの配列がプリミティブ型である場合の違いを作ります。たとえば、次の場合:

Arrays.stream(someArray)

someArrayでありlong[]、を返しますLongStreamStream.of()一方、はStream<long[]>単一の要素を持つを返します。


1
@Dima確かに、それでもArrays.stream()機能します
fge

2
さて、ストリームに関しては、便利です!プリミティブ配列を処理する*Stream.of()ときに呼び出す必要はありませんArrays.stream()。実際のオブジェクトではない配列については、これはJavaです。これは1.0以降のケースなので、対処してください。この上陰気ても何も助けない
FGE

2
@Dimaなどはあなたのものです。不便だ思いますArrays.stream()、便利だと思います。十分に言った。
2015年

2
@Dimaはい、私はあなたの主張が誤解を招くの*Stream.of()により便利であると思います。それは好みの問題だからです。私Arrays.stream()はそのような場合を好む、それStream.of()はより便利である一般的なルールとしてそれを誤らせる(ペアノ代数)。
2015年

3
@Dima:それは好みの問題です。違いは非常に小さいため、まったく問題になりません。より具体的には、数文字の違いは何もありません標準ライブラリ内のパッケージへの追加のインポートは何もありません。そして、実際には、varargsオーバーロードの代わりに手動で配列を作成することは何もありません
Jeroen Vannevel

14
Stream.of("foo", "bar", "baz")

または、すでに配列がある場合は、次のようにすることもできます

Stream.of(array) 

プリミティブ型の使用のためIntStream.ofか、LongStream.ofなど


私が理解していないのは、int[]可変引数を受け入れるメソッドにを渡すことができるときにStream.of(intArray)Stream<Integer>代わりにを生成しないのはなぜStream<int[]>ですか?また、プリミティブ用の特殊なStreamクラスがある理由には、技術的な理由がありますか?
asgs

1
Javaプリミティブは奇妙な獣です。int[]他の配列とは異なります。それはのサブクラスではないのですObject[]が、それはあるのサブクラスObject。したがって、それをStream.ofに渡すと、それがObject、パラメータとして取得され、のストリームを取得しますint[]。これが、プリミティブ専用のクラスを用意する理由の1つです。プリミティブ配列からストリームを作成しなかった場合、かなり苦痛になります。もう1つの理由は、Objectボックス化(通常のオブジェクトのように見えるように変換するintこと)によるオーバーヘッドを発生させる必要がないため、特殊なクラスの方が効率的であることIntegerです。
Dima

ああ、int[]はなので、Objectオーバーロードされたメソッドof(T t)と一致するため、を返しますStream<int[]>。だから、理論的に言えば、この方法が利用できない場合、私たちはStream<Integer>見返りを得たでしょうか?または、一致するメソッドが見つからなかったためにコンパイルエラーが発生したのでしょうか?つまりint[]、次のように扱うことはできませんT...
asgs

1
いいえ、まだ同じように一致するStream<Integer>ので、私たちはまだそのようにはなりませんStream.of(t ... T)
Dima

0

並列オプションのある低レベルの方法でも作成できます。

更新:(length-1ではなく)完全なarray.lengthを使用します。

/** 
 * Creates a new sequential or parallel {@code Stream} from a
 * {@code Spliterator}.
 *
 * <p>The spliterator is only traversed, split, or queried for estimated
 * size after the terminal operation of the stream pipeline commences.
 *
 * @param <T> the type of stream elements
 * @param spliterator a {@code Spliterator} describing the stream elements
 * @param parallel if {@code true} then the returned stream is a parallel
 *        stream; if {@code false} the returned stream is a sequential
 *        stream.
 * @return a new sequential or parallel {@code Stream}
 *
 * <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel)
 */

StreamSupport.stream(Arrays.spliterator(array, 0, array.length), true)

0

Arrays.streamを使用できます。

Arrays.stream(array); 

これがその場合はご使用のアレイ入力タイプに基づいて、蒸気の戻り値の型を確保しString []、その後復帰Stream<String>すると、int []その後、戻ってIntStream

入力タイプの配列がすでにわかっている場合は、入力タイプのような特定の配列を使用するのが良い int[]

 IntStream.of(array); 

これはIntstreamを返します。

最初の例では、Javaはmethod overloadingを使用して入力タイプに基づいて特定のメソッドを検索します。


0

めったに見られませんが、これが最も直接的な方法です

Stream.Builder<String> builder = Stream.builder();
for( int i = 0; i < array.length; i++ )
  builder.add( array[i] );
Stream<String> stream = builder.build();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.