Эффективный способ сопоставления ключей первой карты со значениями второй карты, где значения первых карт являются ключами второй карты - PullRequest
0 голосов
/ 28 января 2020

Предположим, есть 2 карты, так что значения 1-й карты являются ключами 2-й карты, как показано ниже

Map1 { k1:[v1,v2,v3], k2:[v4,v5], k3:[v6,v7,v8] }
Map2 { v1:[a1,a2], v2:[a3,a4,a5], v3:[a6], v4:[a7,a8], v5:[a9,a10,a11], v6[a1,a3], v7[a1,a9], v8[a2,a4,a5] }  

Я хочу сделать карту, скажем, Map3 из 2-х вышеуказанных карт, такую, что

Map3 { 
    k1:[a1,a2,a3,a4,a5,a6],
    k2:[a7,a8,a9,a10,a11],
    k3:[a1,a2,a3,a4,a5,a9]
    }

Существуют ли какие-либо встроенные методы в Java8 Collections API, которые я могу использовать для эффективного извлечения Map3, вместо того, чтобы перебирать обе карты, чтобы получить Map3 старым способом Java5.

Ответы [ 3 ]

2 голосов
/ 28 января 2020

Альтернативное решение:

Map<String, List<String>> result  = 
    map1.entrySet().stream()
            .collect(HashMap::new, (m, e) -> m.merge(e.getKey(),
                    e.getValue().stream().flatMap(k -> map2.get(k).stream()).collect(toList()),
                    (l1, l2) -> { l1.addAll(l2);return l1; }),
                    Map::putAll);
0 голосов
/ 28 января 2020

Вот решение с использованием потоков:

return map1.entrySet().stream().collect(
    Collectors.toMap(
        Map.Entry::getKey,
        e -> e.getValue().stream()
            .map(map2::get)
            .flatMap(List::stream)
            .distinct()
            .collect(Collectors.toList())));

Вывод:

{k1=[a1, a2, a3, a4, a5, a6],
 k2=[a7, a8, a9, a10, a11],
 k3=[a1, a3, a9, a2, a4, a5]}

Вы можете добавить .sorted() после .distinct(), если хотите, чтобы список k3 находился в заказ.

0 голосов
/ 28 января 2020

Я бы подошел к этому так.

  1. K - это тип ключа первой карты и тип ключа возвращаемой карты
  2. V - тип ключа для второй карты и значения введите первую карту
  3. R - это тип возвращаемой карты.

В вашем примере, предполагая, что все типы имеют тип String, назовите его следующим образом.

    Map<String,Set<String>> map3 = reMap(map1,map2);

        public static <K, V, R> Map<K, Set<R>> reMap(
            Map<K, List<V>> map1, Map<V, List<R>> map2) {

        Map<K, Set<R>> map3 = new HashMap<>();

        for (Map.Entry<K, List<V>> e : map1.entrySet()) {
            for (V map2key : e.getValue()) {
                map3.compute(e.getKey(),
                        (k, v) -> v == null
                                ? new HashSet<>()
                                : v)
                        .addAll(map2.get(map2key));
            }
        }
        return map3;
    }
...