Java 8 Stream e operazioni su array


197

Ho appena scoperto le nuove funzionalità del flusso Java 8. Provenendo da Python, mi chiedevo se ora ci fosse un modo pulito per eseguire operazioni su array come il summing, moltiplicando due array in modo "una linea pitonica"?

Grazie

Risposte:


294

Sono stati aggiunti nuovi metodi java.util.Arraysper convertire un array in un flusso Java 8 che può quindi essere utilizzato per la somma ecc.

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

Moltiplicare due matrici è un po 'più difficile perché non riesco a pensare a un modo per ottenere il valore E l'indice contemporaneamente a un'operazione Stream. Ciò significa che probabilmente dovrai eseguire lo streaming sopra gli indici dell'array.

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

MODIFICARE

Commenter @Holger sottolinea che è possibile utilizzare il mapmetodo anziché in forEachquesto modo:

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 sì, funzionerebbe anche questo. Anche se probabilmente si desidera utilizzare mapToIntper evitare la boxe.
dkatzel,

Quest'ultimo equivale a una simulazione di zip in cui è necessario preallocare l'archiviazione per il risultato. Mi chiedo perché non ci sia zip nella libreria Stream?
Reb.Cabin

Secondo questa risposta SO , un zip era in una beta precedente di Java 8, quindi rimosso. Fortunatamente il poster aveva la fonte ed è nella risposta. Ho usato il codice più volte e sembra funzionare molto bene.
sparc_spread,

@dkatzel - Poiché è già un IntStream, "map" accetta un IntUnaryOperator, quindi non è coinvolto il pugilato.
M. Justin,

58

Puoi trasformare un array in un flusso usando Arrays.stream():

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

Una volta ottenuto il tuo stream, puoi utilizzare uno qualsiasi dei metodi descritti nella documentazione , come sum()o altro. È possibile mapo filtergradire in Python chiamando i metodi di streaming pertinenti con una funzione Lambda:

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

Una volta terminata la modifica del flusso, si chiama quindi toArray()per riconvertirlo in un array da utilizzare altrove:

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

Fai attenzione se hai a che fare con numeri grandi.

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

La somma sopra non lo è 2 * Integer.MIN_VALUE. Devi farlo in questo caso.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.