2016-04-25 20 views
29

Esiste un metodo sum() equivalente nel flusso che può eseguire la moltiplicazione dei valori dati in un flusso?Come moltiplicare i valori in un elenco utilizzando java 8 stream

Ho una lista di interi in questo modo:

List<Integer> listOfIntegers = new ArrayList<>(); 
listOfIntegers.addAll(Arrays.asList(1,4,2,7,5)); 

Sono in grado di ottenere la somma di tutti i numeri interi, ma incapace di trovare un'API in grado di moltiplicare i valori e dare l'uscita.

listOfIntegers.stream().mapToInt(a -> a).sum(); 

Se provo ad usare forEach per farlo, allora non posso memorizzare il risultato come uniche variabili finali sono autorizzati per essere utilizzati all'interno di esso.

C'è qualche alternativa a questo?

+0

Dai uno sguardo a questo link probabilmente avrai la risposta. http://codereview.stackexchange.com/questions/78484/multiplying-corresponding-integers-using-spread –

risposta

37

Provare a ridurre i flussi, dovrebbe essere d'aiuto.

come:

listOfIntegers.stream().reduce(1, (a, b) -> a * b) 

Questo link fornisce ulteriori informazioni su come utilizzare ridurre.

+6

Naturalmente, non è necessario inserire i valori per primi: 'IntStream.of (1,4,2,7 , 5). Riduzione (1, (a, b) -> a * b) ' – Andreas

+0

@Andreas Concordato. Dato che la lista era già disponibile, ho fatto uso del flusso. Karthik come Andreas ha suggerito di poter utilizzare direttamente IntStream se hai i valori. –

+1

Se stai ottenendo un 'Optional', puoi lasciare il primo argomento a' reduce'. – Zirak

28

Una cosa da tenere a mente quando si moltiplica un numero sconosciuto di ints è la possibilità di overflow. Piuttosto che (a,b) -> a*b, è più sicuro da usare Math::multiplyExact, che sarà un'eccezione in caso di overflow:

listOfIntegers.stream().mapToInt(x->x).reduce(1, Math::multiplyExact); 

In alternativa, è possibile ospitare grandi risultati, riducendo il BigInteger:

listOfIntegers.stream() 
    .map(BigInteger::valueOf) 
    .reduce(BigInteger.ONE, BigInteger::multiply); 

di riduzione con un'identità sarà restituire 1 o BigInteger.ONE se l'elenco è vuoto, che potrebbe non essere quello che si desidera. Se si desidera gestire il caso di un elenco vuoto, rimuovere il primo argomento su reduce e quindi gestire il risultante Optional.