2016-04-17 19 views
5

Sto cercando di convertire questo:Contatore con lambda su carta java8

Map<String,Long> parties = new HashMap<>(); 
parties.add("a", 1); 
... 
Long counter = 0l; 

for (Long votes : parties.values()){ 
    counter += votes; 
} 

Per lambda in Java8, ho provato con ridurre in questo modo:

parties.entrySet().stream().reduce((stringLongEntry, stringLongEntry2) -> /*Here I Stack*/) 

Ma io non so come continuare.

PS: So che posso farlo con: parties.values().stream().count(); ma voglio trovare un altro approccio

+1

Perché vuoi trovare un altro modo? – fge

+0

Stai sempre memorizzando 1 nei tuoi valori? In questo caso, la dimensione della mappa è tutto ciò di cui hai bisogno. –

+0

@FedericoPeraltaSchaffner no Non ho messo via 1, era solo un esempio –

risposta

4

provare la seguente espressione:

counter = parties.values().stream().map((votes) -> votes).reduce(counter, (a, i) -> a+i); 

Inoltre ci sono alcuni errori nel codice:

  • Uso Map<String,Long> parties = new HashMap<>(); è il modo corretto però uno è il tuo errorneous ot.
  • HashMap non hai .add(..) metodo, ma .put(..) metodo:

    parties.put("a",1L); 
    
  • Dal momento che il valore è Long, è necessario utilizzare 1L o 1l invece di tutta la 1 per specificare un valore Long.

+2

Preferirei scrivere 'L' piuttosto che' l', perché l'ultimo uno sembra '1' – Andrew

+0

Sì, giusto. Io faccio lo stesso :) –

+1

Non c'è bisogno di 'map' se lo stai facendo in questo modo (non fa altro che aggiungere caratteri al tuo codice) ... Comunque, preferisco usare LongStream mentre manipolo i valori primitivi. –

2
  1. parties.values().stream().mapToLong(l -> l).sum();
  2. parties.values().stream().reduce(0L, (a, b) -> a + b);

  1. parties.entrySet().stream().mapToLong(Map.Entry::getValue).sum();
  2. parties.entrySet().stream().mapToLong(Map.Entry::getValue).reduce(0L, (a, b) -> a + b);

La spiegazione per la domanda nei commenti. Qui possiamo scrivere sia (Map.Entry<String, Long> i) -> i.getValue() o i -> i.getValue(). Ma sarà più leggibile se lo sostituiamo per un method reference come Map.Entry::getValue.

+2

'1.' è sbagliato, vuole la somma, non il conteggio. –

+1

@NikolasCharalambidis, grazie – Andrew

+1

Grazie per la risposta, sono nuovo con lambda, cosa significa "::"? –

2

se ti ostini a entrySet -

parties.entrySet().stream().map(e -> e.getValue()).reduce(0L, (longValue1, longValue2) -> longValue1 + longValue2) 
5

Se siete sempre archiviano 1 come valore per ogni tasto, quindi il numero totale sarà sempre corrispondere alle dimensioni della mappa. Puoi farlo semplicemente con parties.size().

Se si memorizzano valori diversi per ogni chiave, quindi il conteggio di quanti valori si hanno nella mappa è errato. Dovresti sommarli:

long total = parties.values().stream().mapToLong(v -> v).sum(); 
+0

Ciao, l'1 era solo un esempio, può essere qualsiasi numero Lungo. E riguardo alla tua risposta la tua soluzione è esattamente come la mia. Qui hai la documentazione di conteggio: Restituisce il conteggio degli elementi in questo flusso. Questo è un caso speciale di a reduction ed è equivalente a:

{@code return mapToLong(e -> 1L).sum(); }

+0

@RobertoFernandez Non è uguale al tuo. Contare su n equivale a sommare 1 n volte, è quello che dicono i dottori. Ma se hai valori diversi da 1 nella mappa, count() e sum() restituiranno valori diversi –