Java 8 Stream et fonctionnement sur les tableaux

197

Je viens de découvrir les nouvelles capacités de flux Java 8. Venant de Python, je me demandais s'il y avait maintenant une façon ordonnée de faire des opérations sur des tableaux comme la sommation, en multipliant deux tableaux d'une manière "pythonique d'une ligne"?

Merci

BlackLabrador
la source

Réponses:

294

De nouvelles méthodes ont été ajoutées pour java.util.Arraysconvertir un tableau en un flux Java 8 qui peut ensuite être utilisé pour sommer etc.

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

La multiplication de deux tableaux est un peu plus difficile car je ne peux pas penser à un moyen d'obtenir la valeur ET l'index en même temps qu'une opération Stream. Cela signifie que vous devrez 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]);

ÉDITER

Commenter @Holger souligne que vous pouvez utiliser la mapméthode au lieu de forEachcomme ceci:

int[] result = IntStream.range(0, a.length).map(i -> a[i] * b[i]).toArray();
dkatzel
la source
13
int[] result=IntStream.range(0, a.length).map( i->a[i]* b[i]).toArray();
Holger
2
@ Holger oui, cela fonctionnerait aussi. Bien que vous souhaitiez probablement l'utiliser mapToIntpour éviter la boxe.
dkatzel
Ce dernier équivaut à une simulation de zip où vous devez préallouer du stockage pour le résultat. Je me demande pourquoi il n'y a pas de zip dans la bibliothèque Streams?
Reb.Cabin
Selon cette réponse SO , un zip était dans une version bêta antérieure de Java 8, puis retiré. Heureusement, l'affiche avait la source et c'est dans la réponse. J'ai utilisé le code plusieurs fois et il semble très bien fonctionner.
sparc_spread
@dkatzel - Comme il s'agit déjà d'un IntStream, "map" prend un IntUnaryOperator, donc il n'y a pas de boxe impliquée.
M. Justin
58

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. Vous pouvezmap ou filteraimer en Python en appelant les méthodes de flux pertinentes 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 un 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();
Ian Knight
la source
9

Soyez prudent si vous devez composer avec 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 ne l'est pas 2 * Integer.MIN_VALUE. Vous devez le faire dans ce cas.

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