2015-11-10 10 views
27

Sto cercando di convertire un Map<String, List<String>> ad un Map<String, String>, in cui il valore per ogni chiave è la stringa congiunta costruita unendo tutti i valori nella List nella mappa precedente, ad esempio:Partecipare a un elenco <String> all'interno di una mappa

A -> ["foo", "bar", "baz"] 
B -> ["one", "two", "three"] 

devono essere convertiti in

A -> "foo|bar|baz" 
B -> "one|two|three" 

Qual è il modo idiomatico di farlo usando lo Streams API Java 8?

risposta

30

Per questa attività è possibile utilizzare Collectors.joining(delimiter).

Map<String, String> result = map.entrySet() 
           .stream() 
           .collect(toMap(
            Map.Entry::getKey, 
            e -> e.getValue().stream().collect(joining("|"))) 
           ); 

In questo codice, ogni voce nella mappa sono raccolte per una nuova mappa in cui:

  • la chiave rimane lo stesso
  • il valore, che è una lista, viene raccolto a un String unendo insieme tutti gli elementi
6

Google Guava ha un metodo di supporto bella per questo:

com.google.common.collect.Maps.transformValues(map, x -> x.stream().collect(joining("|"))); 

utilizzando Java puro, questo dovrebbe funzionare:

map.entrySet().stream().collect(toMap(Entry::getKey, e -> e.getValue().stream().collect(joining("|")))); 
+3

Va notato che 'Maps.transformValues' non lo fa creare una mappa integrale indipendente, ma una vista della mappa originale. –

41

Semplicemente usano String.join, non c'è bisogno di creare il flusso nidificato:

Map<String, String> result = map.entrySet() 
          .stream() 
          .collect(toMap(
           e -> e.getKey(), 
           e -> String.join("|", e.getValue()))); 
Problemi correlati