Как создать обратную карту, когда исходная карта содержит коллекцию в качестве значения? - PullRequest
0 голосов
/ 15 февраля 2019

Допустим, мой оригинал Map содержит следующее:

Map<String, Set<String>> original = Maps.newHashMap();
original.put("Scott", Sets.newHashSet("Apple", "Pear", "Banana");
original.put("Jack", Sets.newHashSet("Banana", "Apple", "Orange");

И я хочу создать обратное Map, содержащее следующее:

  "Apple":  ["Scott", "Jack"]
  "Pear":   ["Scott"]
  "Banana": ["Scott", "Jack"]
  "Orange": ["Jack"]

Я знаю, что это можетбыть сделано по старинке (до Java 8), но как мне добиться того же, используя Java Stream API?

Map<String, Set<String>> reversed = original.entrySet().stream().map(x -> ????).collect(??)

Здесь размещен аналогичный вопрос здесь , но он работает только для однозначных Map с.

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Более императивным, но более простым решением было бы использование forEach:

Map<String, Set<String>> original,result; // initialised
original.forEach((key, value) -> value.forEach(v -> 
            result.computeIfAbsent(v, k -> new HashSet<>()).add(key)));
0 голосов
/ 15 февраля 2019

Вы можете разбить Map на пары ключ-значение (где каждый ключ и значение - один String), используя flatMap, а затем собрать их по своему желанию:

Map<String,Set<String>> rev =
    original.entrySet ()
            .stream ()
            .flatMap (e -> e.getValue ()
                            .stream ()
                            .map (v -> new SimpleEntry<String,String>(v,e.getKey ())))
            .collect(Collectors.groupingBy (Map.Entry::getKey,
                                            Collectors.mapping (Map.Entry::getValue, 
                                                                Collectors.toSet())));
System.out.println (rev);

Выход:

{Apple=[Jack, Scott], Pear=[Scott], Orange=[Jack], Banana=[Jack, Scott]}
...