web-dev-qa-db-fra.com

Java 8 Flux et fonctionnement sur des tableaux

Je viens de découvrir les nouvelles capacités de flux Java 8. Venant de Python, je me demandais s’il existait maintenant un moyen astucieux d’effectuer des opérations sur des tableaux comme sommer, multipliant deux tableaux de manière "une ligne Pythonic"?

Merci

189
BlackLabrador

De nouvelles méthodes ont été ajoutées à Java.util.Arrays pour convertir un tableau en un flux Java 8 pouvant ensuite être utilisé pour la somme, etc.

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

Multiplier deux tableaux est un peu plus difficile, car je ne vois pas comment obtenir la valeur ET l'indice en même temps qu'une opération Stream. Cela signifie que vous devez probablement diffuser sur les index du tableau.

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

EDIT

Commenter @ Holger indique que vous pouvez utiliser la méthode map à la place de forEach comme ceci:

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

Vous pouvez transformer un tableau en flux en utilisant Arrays.stream():

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

Une fois que vous avez votre flux, vous pouvez utiliser l’une des méthodes décrites dans la documentation , comme sum() ou autre chose. Vous pouvez map ou filter comme dans Python en appelant les méthodes de flux appropriées avec une fonction Lambda:

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

Une fois que vous avez fini de modifier votre flux, vous appelez ensuite toArray() pour le reconvertir en tableau à utiliser ailleurs:

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

Faites attention si vous devez faire face à un grand nombre.

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

La somme ci-dessus n'est pas 2 * Integer.MIN_VALUE. Vous devez faire cela dans ce cas.

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

Veuillez noter que Arrays.stream (arr) crée un LongStream (ou IntStream, ...) au lieu de Stream afin que la fonction map ne puisse pas être utilisée pour modifier le type. C'est pourquoi les fonctions .mapToLong, mapToObject, ... sont fournies.

Jetez un oeil à pourquoi-cant-i-map-entier-à-chaînes-quand-streaming-from-an-array

3
Rafael