我有两个HashMap对象,定义如下:

HashMap<String, Integer> map1 = new HashMap<String, Integer>();
HashMap<String, Integer> map2 = new HashMap<String, Integer>();

我还有第三个HashMap对象:

HashMap<String, Integer> map3;

如何将map1和map2合并为map3?


当前回答

您可以使用- addAll方法

http://download.oracle.com/javase/6/docs/api/java/util/HashMap.html

但是总会有这样的问题,如果你的两个哈希映射有相同的键,那么它会用第二个哈希映射的键值覆盖第一个哈希映射的键值。

为了安全起见-更改键值-您可以在键上使用前缀或后缀-(第一个哈希映射使用不同的前缀/后缀,第二个哈希映射使用不同的前缀/后缀)

其他回答

使用Java 8 Stream API的一行程序:

map3 = Stream.of(map1, map2).flatMap(m -> m.entrySet().stream())
       .collect(Collectors.toMap(Entry::getKey, Entry::getValue))

该方法的好处之一是能够传递一个merge函数,该函数将处理具有相同键的值,例如:

map3 = Stream.of(map1, map2).flatMap(m -> m.entrySet().stream())
       .collect(Collectors.toMap(Entry::getKey, Entry::getValue, Math::max))

很晚了,但让我分享一下当我遇到同样的问题时我是怎么做的。

Map<String, List<String>> map1 = new HashMap<>();
map1.put("India", Arrays.asList("Virat", "Mahi", "Rohit"));
map1.put("NZ", Arrays.asList("P1","P2","P3"));

Map<String, List<String>> map2 = new HashMap<>();
map2.put("India", Arrays.asList("Virat", "Mahi", "Rohit"));
map2.put("NZ", Arrays.asList("P1","P2","P4"));

Map<String, List<String>> collect4 = Stream.of(map1, map2)
                .flatMap(map -> map.entrySet().stream())
                .collect(
                        Collectors.toMap(
                                Map.Entry::getKey,
                                Map.Entry::getValue,
                                (strings, strings2) -> {
                                    List<String> newList = new ArrayList<>();
                                    newList.addAll(strings);
                                    newList.addAll(strings2);
                                    return newList;
                                }
                        )
                );
collect4.forEach((s, strings) -> System.out.println(s+"->"+strings));

它给出以下输出

NZ->[P1, P2, P3, P1, P2, P4]
India->[Virat, Mahi, Rohit, Virat, Mahi, Rohit]

如果知道没有重复的键,或者希望map2中的值覆盖map1中的值以获得重复的键,那么可以只写

map3 = new HashMap<>(map1);
map3.putAll(map2);

如果需要更多地控制值的组合方式,可以使用Map。merge,在Java 8中添加,它使用用户提供的biffunction来合并重复键的值。merge操作单独的键和值,因此需要使用循环或Map.forEach。这里我们连接重复键的字符串:

map3 = new HashMap<>(map1);
for (Map.Entry<String, String> e : map2.entrySet())
    map3.merge(e.getKey(), e.getValue(), String::concat);
//or instead of the above loop
map2.forEach((k, v) -> map3.merge(k, v, String::concat));

如果你知道你没有重复的键,并且想要强制它,你可以使用merge函数抛出AssertionError:

map2.forEach((k, v) ->
    map3.merge(k, v, (v1, v2) ->
        {throw new AssertionError("duplicate values for key: "+k);}));

从这个特定的问题后退一步,Java 8流库提供了toMap和groupingBy collector。如果在循环中重复合并映射,则可以重新构造计算以使用流,这既可以澄清代码,又可以使用并行流和并发收集器轻松实现并行。

    HashMap<Integer,String> hs1 = new HashMap<>();
    hs1.put(1,"ram");
    hs1.put(2,"sita");
    hs1.put(3,"laxman");
    hs1.put(4,"hanuman");
    hs1.put(5,"geeta");

    HashMap<Integer,String> hs2 = new HashMap<>();
    hs2.put(5,"rat");
    hs2.put(6,"lion");
    hs2.put(7,"tiger");
    hs2.put(8,"fish");
    hs2.put(9,"hen");

    HashMap<Integer,String> hs3 = new HashMap<>();//Map is which we add

    hs3.putAll(hs1);
    hs3.putAll(hs2);

    System.out.println(" hs1 : " + hs1);
    System.out.println(" hs2 : " + hs2);
    System.out.println(" hs3 : " + hs3);

重复的项目将不会被添加(即重复的键),因为当我们将打印hs3时,我们将只获得键5的一个值,这将是最后一个添加的值,它将是rat。 **[设置不允许重复键,但值可以重复]

组合两个可能共享公共键的映射的通用解决方案:

就地:

public static <K, V> void mergeInPlace(Map<K, V> map1, Map<K, V> map2,
        BinaryOperator<V> combiner) {
    map2.forEach((k, v) -> map1.merge(k, v, combiner::apply));
}

返回一个新地图:

public static <K, V> Map<K, V> merge(Map<K, V> map1, Map<K, V> map2,
        BinaryOperator<V> combiner) {
    Map<K, V> map3 = new HashMap<>(map1);
    map2.forEach((k, v) -> map3.merge(k, v, combiner::apply));
    return map3;
}