如何将Java的hashMap内容全部放在一起,但不能替换现有的键和值?

时间:2011-08-25 17:19:59

标签: java map hashmap

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

最好的办法是什么?

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

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

8 个答案:

答案 0 :(得分:99)

看起来你愿意创建一个临时的Map,所以我会这样做:

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

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

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

patch.forEach(target::putIfAbsent);

答案 1 :(得分:15)

使用GuavaMaps类'实用程序方法来计算2个地图的差异,您可以在一行中执行此操作,并使用方法签名可以更清楚地了解您要尝试的内容完成:

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

答案 2 :(得分: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中的所有条目

答案 3 :(得分:5)

如果你在@ erickson的解决方案中更改地图顺序,你可以只用一行:

dplyr::arrange(dat_4, id, datastate, timebucket)
#    id timebucket  datastate   t actual naive
# 1   A 2015-06-01 2015-07-01 t-1    310    NA
# 2   A 2015-07-01 2015-07-01   t    510   310
# 3   A 2015-08-01 2015-07-01 t+1     NA   310
# 4   A 2015-07-01 2015-08-01 t-1    510    NA
# 5   A 2015-08-01 2015-08-01   t    710   510
# 6   A 2015-09-01 2015-08-01 t+1     NA   510
# 7   A 2015-08-01 2015-09-01 t-1    710    NA
# 8   A 2015-09-01 2015-09-01   t    178   710
# 9   A 2015-10-01 2015-09-01 t+1     NA   710
# 10  B 2015-06-01 2015-07-01 t-1    320    NA
# 11  B 2015-07-01 2015-07-01   t    520   320
# 12  B 2015-08-01 2015-07-01 t+1     NA   320
# 13  B 2015-07-01 2015-08-01 t-1    520    NA
# 14  B 2015-08-01 2015-08-01   t    720   520
# 15  B 2015-09-01 2015-08-01 t+1     NA   520
# 16  B 2015-08-01 2015-09-01 t-1    720    NA
# 17  B 2015-09-01 2015-09-01   t    180   720
# 18  B 2015-10-01 2015-09-01 t+1     NA   720

在这种情况下,您将mapWithNotSoImportantValues中的值替换为mapWithImportantValues中具有相同键的值。

答案 4 :(得分: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);
}}

答案 5 :(得分:2)

使用Java 8,有一种API方法可以满足您的需求。

map.putIfAbsent(key, value)

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

答案 6 :(得分:2)

使用 Map#merge 的 Java 8 解决方案

开始,您可以使用 Map#merge(K key, V value, BiFunction remappingFunction),它使用 Map 将值合并到 remappingFunction 中,以防已在 Map 中找到您想把这对放进去。

// using lambda
newMap.forEach((key, value) -> map.merge(key, value, (oldValue, newValue) -> oldValue));
// using for-loop
for (Map.Entry<Integer, String> entry: newMap.entrySet()) {
    map.merge(entry.getKey(), entry.getValue(), (oldValue, newValue) -> oldValue);
}

代码迭代 newMap 条目(keyvalue),每个条目都通过 map 方法合并到 merge 中。在重复键的情况下触发 remappingFunction,在这种情况下,它表示将使用前(原始)oldValue 值而不是重写。

使用此解决方案,您不需要临时 Map


让我们举个例子,将 newMap 条目合并到 map 中,并保留原始值以防重复。

Map<Integer, String> newMap = new HashMap<>();
newMap.put(2, "EVIL VALUE");                         // this will NOT be merged into
newMap.put(4, "four");                               // this WILL be merged into
newMap.put(5, "five");                               // this WILL be merged into

Map<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");

newMap.forEach((k, v) -> map.merge(k, v, (oldValue, newValue) -> oldValue));

map.forEach((k, v) -> System.out.println(k + " " + v));
<块引用>
1 one
2 two
3 three
4 four
5 five

答案 7 :(得分:0)

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

mapToInsert.forEach(originalMap::putIfAbsent);