You can do it like this.
The data
Map<String, List<String>> map = Map.of("North America",
List.of("New York", "Vancouver", "Paris"), "Europe",
List.of("London", "Paris"));
The process
- stream the
entrySet
flatMap
the list and map to an array
- then build the new map with the results of the array.
- I added a merge function to handle duplicate keys in case a city is in two countries.
Map<String, String> result = map.entrySet().stream()
.flatMap(e -> e.getValue().stream()
.map(str -> new String[] { str, e.getKey() }))
.collect(Collectors.toMap(a -> a[0], a -> a[1],
(countries, country)->countries + ", " + country,
HashMap::new));
result.entrySet().forEach(System.out::println);
prints
New York=North America
Vancouver=North America
London=Europe
Paris=Europe, North America
Instead of using string concatenation to handle duplicates you could also do this using a Map<String,List<String>>
to handle duplicate cities. Here is how that would look.
Map<String, List<String>> result = map.entrySet().stream()
.flatMap(e -> e.getValue().stream()
.map(str -> new String[] { str, e.getKey() }))
.collect(Collectors.groupingBy(a -> a[0],
Collectors.mapping(a -> a[1], Collectors.toList())));