2015-11-10 22 views
27

Próbuję przekonwertować Map<String, List<String>> do Map<String, String>, gdzie wartość dla każdego klucza jest wspólny łańcuch zbudowany przez złączenie wszystkich wartości w List w poprzedniej mapie, npŁączenie listy <String> wewnątrz mapie

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

powinny być zamienione na

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

Jaka jest idiomatyczne sposób to zrobić przy użyciu Java 8 Streams API?

Odpowiedz

30

Do wykonania tego zadania można użyć Collectors.joining(delimiter).

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

W tym kodzie, każdy wpis w mapie są zbierane do nowej mapie gdzie:

  • kluczem pozostaje taka sama
  • wartość, która jest na liście, jest zbierany do String poprzez połączenie wszystkich elementów razem
6

Google Guava ma ładny metody pomocnika dla tego:

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

użyciu czystego java, to będzie działać:

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

Należy zauważyć, że 'Maps.transformValues' nie utwórz niezależną mapę dosłowną, ale zamiast tego wyświetl oryginalną mapę. –

41

Wystarczy użyć String.join, nie ma potrzeby, aby utworzyć zagnieżdżony strumień:

Map<String, String> result = map.entrySet() 
          .stream() 
          .collect(toMap(
           e -> e.getKey(), 
           e -> String.join("|", e.getValue()))); 
Powiązane problemy