简体   繁体   English

将第一个映射的键映射到第二个映射的值的有效方法,其中第一个映射的值是第二个映射的键

[英]Efficient way of mapping keys of first map to values of second map, where value of first maps are keys of second map

Suppose there are 2 maps such that values of 1st map are keys of 2nd map, as show below假设有 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] }  

I want to make a map say Map3 from the above 2 maps such that我想从上面的 2 张地图中制作一张地图,比如 Map3,这样

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

Are there any inbuilt methods in Java8 Collections API which I can use to derive Map3 in an efficient way, rather than iterating over both the maps to get Map3 in the old Java5 way. Java8 Collections API 中是否有任何内置方法,我可以使用它以有效的方式派生 Map3,而不是迭代这两个映射以使用旧的 Java5 方式获取 Map3。

Alternative solution is:替代解决方案是:

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);

Here's a solution using streams:这是使用流的解决方案:

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

Output:输出:

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

You can add .sorted() after .distinct() if you want the k3 list to be in order.您可以添加.sorted().distinct()如果你想k3列表是为了。

I would approach it like this.我会像这样接近它。

  1. K is the key type of the first map and key type of returned map K 是第一个映射的键类型和返回映射的键类型
  2. V is the key type for second map and value type in first map V 是第二个映射的键类型和第一个映射中的值类型
  3. R is the returned map's type. R 是返回的地图类型。

In your example, assuming the types are all String, call it it like this.在您的示例中,假设类型都是 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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM