Java 8 Stream und Betrieb auf Arrays


197

Ich habe gerade die neuen Java 8-Stream-Funktionen entdeckt. Als ich aus Python kam, fragte ich mich, ob es jetzt eine gute Möglichkeit gibt, Operationen an Arrays wie Summieren durchzuführen und zwei Arrays auf eine "einzeilige pythonische" Weise zu multiplizieren.

Vielen Dank

Antworten:


294

Es wurden neue Methoden hinzugefügt, java.util.Arraysum ein Array in einen Java 8-Stream zu konvertieren, der dann zum Summieren usw. verwendet werden kann.

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

Das Multiplizieren von zwei Arrays ist etwas schwieriger, da ich mir keine Möglichkeit vorstellen kann, den Wert UND den Index gleichzeitig mit einer Stream-Operation zu erhalten. Dies bedeutet, dass Sie wahrscheinlich über die Indizes des Arrays streamen müssen.

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

BEARBEITEN

Commenter @Holger weist darauf hin, dass Sie die mapMethode anstelle der folgenden verwenden forEachkönnen:

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
@ Holger ja das würde auch funktionieren. Obwohl Sie wahrscheinlich verwenden möchten mapToInt, um Boxen zu vermeiden.
Dkatzel

Letzteres entspricht einer Simulation von zip, bei der Sie den Speicher für das Ergebnis vorab zuweisen müssen. Ich frage mich, warum es in der Streams-Bibliothek keine Zip gibt.
Reb.Cabin

Nach dieser SO-Antwort wurde eine Zip-Datei in einer früheren Beta von Java 8 entfernt. Zum Glück hatte das Poster die Quelle und es ist in der Antwort. Ich habe den Code mehrmals verwendet und er scheint sehr gut zu funktionieren.
sparc_spread

@dkatzel - Da es sich bereits um einen IntStream handelt, benötigt "map" einen IntUnaryOperator, sodass kein Boxen erforderlich ist.
M. Justin

58

Sie können ein Array in einen Stream verwandeln, indem Sie Folgendes verwenden Arrays.stream():

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

Sobald Sie Ihren Stream haben, können Sie eine der in der Dokumentation beschriebenen Methoden verwenden , wie sum()oder was auch immer. Sie können mapoder filtermöchten in Python, indem Sie die relevanten Stream-Methoden mit einer Lambda-Funktion aufrufen:

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

Sobald Sie Ihren Stream geändert haben, rufen Sie ihn toArray()auf, um ihn wieder in ein Array zu konvertieren und an anderer Stelle zu verwenden:

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

Seien Sie vorsichtig, wenn Sie mit großen Zahlen umgehen müssen.

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

Die obige Summe ist nicht 2 * Integer.MIN_VALUE. In diesem Fall müssen Sie dies tun.

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.