2016-02-27 22 views
5

ho qualche difficoltà a trovare un buon approccio/implementazione utilizzando l'API flusso per la seguente:Java 8 Streaming: Raggruppare con aggregazione

Ho una lista di elementi, ogni elemento costituito da una stringa e un intero. Ora mi piace raggruppare gli elementi con i loro valori di stringa, e quindi per ogni gruppo mi piace avere la somma dei valori interi dagli elementi che si riferiscono a quel gruppo.

Esempio: ho i seguenti 3 elementi:

("GroupA", 100) ("GroupA", 50) ("GroupB", 10) 

E come risultato mi piace ottenere una mappa che consiste delle seguenti due (chiave, valore) coppie:

("GroupA, 150) ("GroupB, 10) 

I non sono sicuro di come risolvere questo I più promettenti sono venuto in mente finora è questo:

elements.stream().collect(Collectors.groupingBy(e-> e.getGroup())) 
      .merge(group, elementsOfTheGroup, (...)); 

Ma io non sono sicuro di quale funzione di inserire come ultimo parametro del metodo di unione. Ma non so se dovrei usare il metodo di fusione.

Quale sarebbe l'implementazione più elegante per questo?

risposta

8

È necessario aggiungere un collettore downstream a Collectors.groupingBy(classifier, downstream). Questo collezionista raccoglie tutti gli elementi che sono stati classificati nella stessa chiave. In questo caso, abbiamo solo bisogno di sommare tutti i numeri usando Collectors.summingInt(mapper), con il mapper che è una funzione che restituisce il numero da sommare.

Assumendo questo numero possono essere recuperate con il getter getNumber(), si potrebbe avere:

Map<String, Integer> result = 
    elements.stream().collect(Collectors.groupingBy(
     e -> e.getGroup(), 
     Collectors.summingInt(e -> e.getNumber()) 
    )); 

è possibile utilizzare un metodo di riferimento al posto dei due lambda di cui sopra. Se la classe degli elementi è Element ad esempio, si dovrebbe

Map<String, Integer> result = 
    elements.stream().collect(Collectors.groupingBy(
     Element::getGroup, 
     Collectors.summingInt(Element::getNumber) 
    )); 
+0

grande, grazie! – user3237736