Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 convert Map<K, List<V>> to Map<V, List<K>>

I need to convert Map<K, List<V>> to Map<V, List<K>>. I've been struggling with this issue for some time.

It's obvious how to do conversion Map<K, V> to Map<V, List<K>>:

.collect(Collectors.groupingBy(
     Map.Entry::getKey, 
     Collectors.mapping(Map.Entry::getValue, toList())
)

But I can't find solve an initial issue. Is there some easy-to-ready-java-8 way to do it?

like image 256
Taras Velykyy Avatar asked Aug 16 '18 12:08

Taras Velykyy


1 Answers

I think you were close, you would need to flatMap those entries to a Stream and collect from there. I've used the already present SimpleEntry, but you can use a Pair of some kind too.

initialMap.entrySet()
          .stream()
          .flatMap(entry -> entry.getValue().stream().map(v -> new SimpleEntry<>(entry.getKey(), v)))
          .collect(Collectors.groupingBy(
               Entry::getValue,
               Collectors.mapping(Entry::getKey, Collectors.toList())
         ));

Well, if you don't want to create the extra overhead of those SimpleEntry instances, you could do it a bit different:

    Map<Integer, List<String>> result = new HashMap<>();

    initialMap.forEach((key, values) -> {
        values.forEach(value -> result.computeIfAbsent(value, x -> new ArrayList<>()).add(key));
    });
like image 66
Eugene Avatar answered Sep 23 '22 09:09

Eugene