如何将All放在Java hashMap的内容中,而不是替换现有的键和值?


83

我需要将所有键和值从一个A HashMap复制到另一个B,但不必替换现有键和值。

最好的方法是什么?

我当时在考虑迭代keySet和checkig是否存在,我会

Map temp = new HashMap(); // generic later
temp.putAll(Amap);
A.clear();
A.putAll(Bmap);
A.putAll(temp);

Answers:


108

看来您愿意创建一个临时目录Map,所以我会这样做:

Map tmp = new HashMap(patch);
tmp.keySet().removeAll(target.keySet());
target.putAll(tmp);

patch是您要添加到target地图的地图。

感谢Louis Wasserman,这是一个利用Java 8中新方法的版本:

patch.forEach(target::putIfAbsent);

在这种情况下,您无需执行任何操作,removeAll因为它们无论如何都会被覆盖。
奇闻趣事牧师

@牧师贡佐牧师:被什么覆盖?
埃里克森

@luksmir不,这将删除应保留的现有条目。
erickson

嗨!为什么mapWithValues.putAll(mapWithAnotherValues)不起作用?
betomoretti

15
@erickson一个更紧凑的Java 8版本:patch.forEach(target::putIfAbsent)
Louis Wasserman'1

15

使用Guava的地图类”实用程序方法来计算两张地图之间的差异,您可以在一行中完成此操作,并带有一种方法签名,可以使您更清楚地了解要完成的工作:

public static void main(final String[] args) {
    // Create some maps
    final Map<Integer, String> map1 = new HashMap<Integer, String>();
    map1.put(1, "Hello");
    map1.put(2, "There");
    final Map<Integer, String> map2 = new HashMap<Integer, String>();
    map2.put(2, "There");
    map2.put(3, "is");
    map2.put(4, "a");
    map2.put(5, "bird");

    // Add everything in map1 not in map2 to map2
    map2.putAll(Maps.difference(map1, map2).entriesOnlyOnLeft());
}

8

只需迭代并添加:

for(Map.Entry e : a.entrySet())
  if(!b.containsKey(e.getKey())
    b.put(e.getKey(), e.getValue());

编辑添加:

如果可以对a进行更改,则还可以执行以下操作:

a.putAll(b)

并会完全满足您的需求。(中的所有条目b以及其中的所有条目a都不在中b


1.)entrySet()返回Set<Map.Entry>。2.)没有方法contains(...)java.util.Map
Fabian Barney

有没有更聪明的方法?像Collections实用程序一样?我讨厌到处都是for循环。
rapadura 2011年

1
@AntonioP:到处都是for循环吗?有一个for循环,它尽可能地简单明了。
奇闻趣事牧师

我认为+1可以在Maps不使用原始类型的情况下使用。让自己有点迷惑于Map.Entry :-)
Fabian Barney

@Reverend Gonzo,啊,在代码的其他地方。:) Wont .putAll替换a的现有键和值?这种感觉似乎很糟糕,这似乎是最直接的方法。
rapadura 2011年

5

如果您在@erickson的解决方案中更改地图顺序,则只需1行即可完成:

mapWithNotSoImportantValues.putAll( mapWithImportantValues );

在这种情况下,您可以使用相同的键将mapWithNotSoImportantValues中的值替换为mapWithImportantValues中的值。


2
public class MyMap {

public static void main(String[] args) {

    Map<String, String> map1 = new HashMap<String, String>();
    map1.put("key1", "value1");
    map1.put("key2", "value2");
    map1.put("key3", "value3");
    map1.put(null, null);

    Map<String, String> map2 = new HashMap<String, String>();
    map2.put("key4", "value4");
    map2.put("key5", "value5");
    map2.put("key6", "value6");
    map2.put("key3", "replaced-value-of-key3-in-map2");
    // used only if map1 can be changes/updates with the same keys present in map2.
    map1.putAll(map2);

    // use below if you are not supposed to modify the map1.
    for (Map.Entry e : map2.entrySet())
        if (!map1.containsKey(e.getKey()))
            map1.put(e.getKey().toString(), e.getValue().toString());
    System.out.println(map1);
}}

2

使用Java 8,可以使用此API方法来满足您的要求。

map.putIfAbsent(key, value)

如果指定的键尚未与值关联(或映射为null),则将其与给定值关联并返回null,否则返回当前值。


1
我们可以放putAllIfAbsent吗?那就是我需要的吗?
user1735921

0

正如其他人所说,您可以使用putIfAbsent。遍历要插入的映射中的每个条目,然后在原始映射上调用此方法:

mapToInsert.forEach(originalMap::putIfAbsent);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.