Search code examples
javahashmapguavamultimap

Merge two Maps (Map<String, Map<String, Object>>) with duplicate keys


I have two ImmutableMaps from guava that I am trying to combine them where they can have duplicate keys;

Map<String, Map<String, Object>> map1 = new ImmutableMap.Builder<String, Map<String, Object>>()
        .put("config", ImmutableMap.of(
                "key1", "value1",
                "key2", "value2"))
        .put("categoryapproval", ImmutableMap.of("reason_code", "listing_quality"))
        .build();

Map<String, Map<String, Object>> map2 = new ImmutableMap.Builder<String, Map<String, Object>>()
        .put("config", ImmutableMap.of(
                "key1", "value3",
                "key4", "value4"))
        .build();

So, I can not use putAll() method because it throws DuplicateKeyException which is as expected. The output I am trying to get is like;

"config" --> "key1": {value1, value3},
             "key2": {value2},
             "key4": {value4}

Finally, I have also tried MultiValueMap, however, MultiValueMap keeps values as List where I need to iterate over. In map1 I can get value1 by map1.get("config").get("key1") where value1 can be any kind of object. I appreciate for any kind of help.


Solution

  • You can use Guava's Multimap and Java 8's Map.merge(K, V, BiFunction):

    Map<String, Multimap<String, Object>> merged = new HashMap<>();
    BiFunction<Multimap<String, Object>, Multimap<String, Object>, Multimap<String, Object>> remappingFunction = (value1, value2) -> {
        Multimap<String, Object> multimap = HashMultimap.<String, Object>create();
        multimap.putAll(value1);
        multimap.putAll(value2);
        return multimap;
    };
    map1.forEach((key, value) -> merged.merge(key, Multimaps.forMap(value), remappingFunction));
    map2.forEach((key, value) -> merged.merge(key, Multimaps.forMap(value), remappingFunction));
    merged.get("config").get("key1");
    

    If you are not using Java 8 then you'll need to manage the merging of multimaps in some other way but the idea is the same.