Java 8ストリームと配列の操作


197

新しいJava 8ストリーム機能を発見しました。Pythonから来て、2つの配列を「1行のpythonic」のように乗算する、合計のような配列の操作を実行するためのきちんとした方法があるかどうか疑問に思いました。

ありがとう

回答:


294

java.util.Arrays配列をJava 8ストリームに変換して、合計などに使用できる新しいメソッドが追加されました。

int sum =  Arrays.stream(myIntArray)
                 .sum();

ストリーム操作と同時に値とインデックスを同時に取得する方法を考えることができないため、2つの配列を乗算するのは少し難しいです。これは、おそらく配列のインデックスを介してストリーミングする必要があることを意味します。

//in this example a[] and b[] are same length
int[] a = ...
int[] b = ...

int[] result = new int[a.length];

IntStream.range(0, a.length)
         .forEach(i -> result[i] = a[i] * b[i]);

編集

コメント者@Holgermapは、次のforEachようにする代わりにメソッドを使用できると指摘しています。

int[] result = IntStream.range(0, a.length).map(i -> a[i] * b[i]).toArray();

13
int[] result=IntStream.range(0, a.length).map( i->a[i]* b[i]).toArray();
Holger

2
@ホルガーはいそれはうまくいくでしょう。mapToIntボクシングを避けるために使用したいと思うかもしれませんが。
dkatzel 2014年

最後に、結果のストレージを事前に割り当てる必要があるzipのシミュレーションになります。Streamsライブラリにzipがないのはなぜですか?
Reb.Cabin 2015

このSOの回答によれば、zipはJava 8の初期のベータ版にあり、その後取り出されました。幸いなことに、ポスターには出典があり、それは答えにあります。私はコードを何度か使用しましたが、非常にうまく機能しているようです。
sparc_spread 2016年

@dkatzel —すでにIntStreamであるため、「map」はIntUnaryOperatorを取るため、ボクシングは関与しません。
M.ジャスティン

58

以下を使用して配列をストリームに変換できますArrays.stream()

int[] ns = new int[] {1,2,3,4,5};
Arrays.stream(ns);

ストリームを取得したら、ドキュメントで説明されいるメソッドなどを使用できますsum()。次のことができますmapfilterラムダ関数と関連するストリームメソッドを呼び出すことにより、Pythonで好き:

Arrays.stream(ns).map(n -> n * 2);
Arrays.stream(ns).filter(n -> n % 4 == 0);

ストリームの変更が完了したら、を呼び出しtoArray()て、別の場所で使用するためにそれを配列に変換して戻します。

int[] ns = new int[] {1,2,3,4,5};
int[] ms = Arrays.stream(ns).map(n -> n * 2).filter(n -> n % 4 == 0).toArray();

9

あなたが大きな数を扱う必要がある場合は注意してください。

int[] arr = new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE};
long sum = Arrays.stream(arr).sum(); // Wrong: sum == 0

上記の合計ではありません2 * Integer.MIN_VALUE。この場合、これを行う必要があります。

long sum = Arrays.stream(arr).mapToLong(Long::valueOf).sum(); // Correct

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.