web-dev-qa-db-ja.com

Java 8ストリームと配列に対する操作

私はちょうど新しいJava 8ストリーム機能を発見しました。 Pythonから来た、私は合計、2行の配列を "1行のPythonic"の方法で乗算するような、配列に対する操作を行うためのきちんとした方法があるのだろうかと思いましたか?

ありがとう

186
BlackLabrador

配列をJava 8ストリームに変換するためのJava.util.Arraysに追加された新しいメソッドがあります。これらのメソッドは、その後で加算などに使用できます。

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

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

//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]);

編集

Commenter @ Holger は、このようにmapの代わりにforEachメソッドを使用できることを示します。

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

Arrays.stream()を使って配列をストリームに変えることができます。

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

ストリームを入手したら、sum()など、 ドキュメント で説明されている方法をどれでも使用できます。 Lambda関数を使用して関連するストリームメソッドを呼び出すことで、Pythonのようにmapまたはfilterを実行できます。

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();
56
Ian Knight

大量に対処する必要がある場合は注意してください。

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
9
Sanghyun Lee

Arrays.stream(arr)はStreamではなくLongStream(またはIntStream、...)を作成するので、マップ関数を使用して型を変更することはできません。これが、.mapToLong、mapToObject、...関数が提供される理由です。

なぜ、 配列からのストリーミング時に、整数を文字列にマップすることができます

3
Rafael