【问题标题】:Java merge two mapsJava合并两个地图
【发布时间】:2018-05-03 17:33:32
【问题描述】:

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

我需要从map1 中删除map2 中不存在的所有密钥。 我需要使用这些键下map2 中存在的适当值来更新map1 中的所有键。

这是我当前的代码:

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

我不确定我的代码是否最佳并且可以改进。能否请您说明如何更有效地执行此任务?

【问题讨论】:

  • 根据您的要求,似乎需要将map1 制作成map2 的副本。这是你的意图吗?
  • 是的,我只需创建 map2 的副本并将 map1 设置为该副本
  • 我正在尝试解决以下问题 - stackoverflow.com/questions/50149323/… 所以我尝试在原始地图1 上保留相同的参考,并且不要用新地图替换它。
  • 所以只需 clear()putAll(map2)

标签: java java-8 hashmap


【解决方案1】:

两行就可以实现

此解决方案基于评论(给人的印象是 OP 希望 map1 是 map2 的精确副本)

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

//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(而不是 cmets),如果 map2 中的任何键在 map1 中不存在,则它不应该在 map1 中结束,因此最后一条语句变为

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

【讨论】:

  • 我把第二行改成map1.putAll(map2)
  • @shmosel 啊是的..突然间你似乎得到了所有可能的组合:)
  • 这种方法引入了两个循环。它仍然不是最佳的
  • @MạnhQuyếtNguyễn 我从来没有说过它更理想。
  • @user7 确实,如果你想和 OP 的代码一样,你宁愿需要map2.forEach(map1::replace)。但目前尚不清楚这是否是 OP 真正想要的,所以 map1.clear(); map1.putAll(map2); 实际上可能仍然是正确的。
【解决方案2】:

我认为您可以使用 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 来做。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2017-03-02
      • 2012-02-06
      • 1970-01-01
      • 1970-01-01
      • 2018-10-31
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 2023-03-16
      相关资源
      最近更新 更多