2015-12-28 15 views
18

Ho un List<Valuta> che può essere rappresentato (semplificato) JSON-style:flusso groupingBy: riducendo al primo elemento della lista

[{codice = euro, description = Euro, ratio = 1}, {codice = USD, description = dollari, ratio = 1.1}]

voglio trasformarla in un Map<String, Valuta> come questo:

{EUR = {codice = euro, description = Eur o, ratio = 1}, USD = {codice = USD, description = Dollari, ratio = 1.1}}

ho scritto questo one-liner:

getValute().stream().collect(Collectors.groupingBy(Valuta::getCodice)); 

ma questo restituisce un Map<String, List<Valuta>> invece di quello di cui ho bisogno.

Suppongo che la funzione mapping() funzioni per me, ma non so come.

risposta

22

In realtà, è necessario utilizzare Collectors.toMap qui invece di Collectors.groupingBy:

Map<String, Valuta> map = 
    getValute().stream() 
       .collect(Collectors.toMap(Valuta::getCodice, Function.identity())); 

groupingBy viene utilizzato per raggruppare gli elementi di un flusso sulla base di una funzione di raggruppamento. 2 Elementi di flusso che avranno lo stesso risultato con la funzione di raggruppamento verranno raccolti in un List per impostazione predefinita.

toMap raccoglierà gli elementi in un Map dove la chiave è il risultato dell'applicazione di un determinato mappatore di chiavi e il valore è il risultato dell'applicazione di un mapper di valori. Notare che toMap, per impostazione predefinita, genererà un'eccezione se viene rilevato un duplicato.

+0

Come fare lo stesso con 'groupingBy'? Non posso usare 'toMap' perché devo aspettarmi chiavi duplicate dal key mapper. Vedo 'groupingBy' ha la firma per il collector downstream come secondo argomento, ma non può farlo funzionare ancora. – user909481

0

E 'un po' tardi nel gioco, ma provate questo:

Map<String, Valuta> map = 
    getValute().stream() 
       .collect(Collectors.groupingBy(Valuta::getCodice, 
          Collectors.collectingAndThen(
           Collectors.toList(), 
           values -> values.get(0)))); 
Problemi correlati