Java合并两个地图

时间:2018-05-03 17:33:32

标签: java java-8 hashmap

我需要通过以下规则合并第一个中的两个地图:

我需要移除map1中不存在的map2中的所有密钥。 我需要使用map1下这些键下的相应值更新map2中的所有键。

这是我目前的代码:

Set<String> keysToRemove = new HashSet<>();
map1.forEach((k, v) -> {
  if (!map2.containsKey(k)) {
    keysToRemove.add(k);
  } else {
    map1.put(k, map2.get(k));
  }
});

for (String k : keysToRemove) {
  map1.remove(k);
}

我不确定我的代码是否最佳并且可以改进。你能否详细说明如何更有效地实施这项任务?

3 个答案:

答案 0 :(得分:2)

你可以用两行来实现它

此解决方案基于评论(由于OP希望map1成为map2的精确副本而给人留下印象)

[...]我试图在原始map1上保留相同的参考,不要用新地图替换它。[原文如此]

//Retains only those keys that are in map2
map1.keySet().retainAll(map2.keySet()); 

//(Possibly) Overwrite value for each key in map2 into map1
map2.forEach(map1::put);

我不相信它会帮助你改善表现。

修改 正如Jacob G.建议的那样,最后一行可以map1.putAll(map2)

<强> EDIT2:

如果我们考虑OP(而不是注释),如果map2中有任何键不在map1中,它不应该在map1中结束,因此最后一个语句变为

map1.forEach((key, value) -> map1.put(key, map2.get(key)));

答案 1 :(得分:0)

我认为您可以使用Iterator

删除第二个循环
Iterator<Map.Entry<K,V>> iter = map1.entrySet().iterator();
while (iter.hasNext()) {
  Map.Entry<K,V> entry = iter.next();
  if(not map2 contain k){
    iter.remove();
  } else {
    entry.put new data
  }
}

此处的关键是,您无法在Map.entrySet()上方循环时更新地图,它会引发ConcurrentModificationException,但您可以使用Iterator进行更新。

答案 2 :(得分:0)

另一种方法可能只是使用map2中可用的键进行过滤,最后使用map将现有值替换为map2上的值。与此类似的东西可能会起到作用:

map1.entrySet().stream().
filter(e -> map2.containsKey(e.getKey())).
map(e -> map2.get(e.getKey()))