在Java中合并两个嵌套映射

问题描述 投票:-2回答:2

我有两个嵌套的地图,我必须合并这两个地图,如果键是相同的,那么它应该合并内部地图,否则保持原样。

Map<String, Map<String, int>> one = new HashMap<>();
Map<String, Map<String, int>> two = new HashMap<>();

one.put("a", someMap1)
one.put("b", someMap2)
two.put("a", someMap3)

resultant mergedMap = (("a", mergeMap(someMap1, someMap3), ("b", someMap2));

如果键是相同的,这将合并映射值。我有与我一起实现的mergeMap()方法。我该如何实现它?

java hashmap java-stream collectors
2个回答
0
投票

这个怎么样(完全未经测试):

static interface Merger<T> {
    T merge(T a, T b);
}

static class IntMerger implements Merger<Integer> {
    @Override
    public Integer merge(Integer a, Integer b) {
        //TODO How do you want to deal with 2 inner maps containing the same entry?
    }
}

static class MapMerger<V> implements Merger<Map<String, V>> {
    private final Merger<V> valueMerger;

    MapMerger(Merger<V> valueMerger) {
        this.valueMerger = valueMerger;
    }

    @Override
    public Map<String, V> merge(Map<String, V> a, Map<String, V> b) {
        Map<String, V> result = new HashMap<>();
        result.putAll(a);
        for(Entry<String, V> ent: b.entrySet()) {
            result.merge(key, val, (a,b)->valueMerger.merge(a,b))
        }
    }
}

public static Map<String, Map<String, Integer>> mergeMaps(
        Map<String, Map<String, Integer>> mapA,
        Map<String, Map<String, Integer>> mapB,) {
    return new MapMerger<>(new MapMerger<>(new IntMerger())).merge(mapA, mapB);
}

0
投票

您可以使用实用程序功能来创建嵌套的地图。

private static <K, V> Map<K, V> innerMerge(K key, V val, BiFunction<V, V, V> function) {
    HashMap<K, V> map = new HashMap<>();
    map.merge(key, val, function);
    return map;
}

Map<Long, Map<Long, String>> groups = new HashMap<>();
groups.merge(groupId, innerMerge(innerGroupId, groupName, (v1, v2) -> v1), (v1, v2) -> {v1.putAll(v2); return v1;});

如果您想要下面的Map Like,请再次使用实用程序功能进行合并。

Map<Long, Map<Long, Map<Long, String>>> groups = new HashMap<>();
// You could use utility function get multi level Map merge
groups.merge(groupId,
   innerMerge(innerGroupId,
      innerMerge(innerAnotherGroupId, groupName, 
      (v1, v2) -> v1 + "," + v2), 
   (v1, v2) -> {v1.putAll(v2); return v1;}),
(v1, v2) -> {v1.putAll(v2); return v1;});

注意:您应该定义自己的BiFunction来操纵现有键的值。

出于您的目的,如果map1和map2签名相同,则可以使用map1.putAll(map2)

© www.soinside.com 2019 - 2024. All rights reserved.