如何在 Java 中复制 HashMap(不是浅拷贝)

新手上路,请多包涵

我需要复制 HashMap<Integer, List<MySpecialClass> > 但是当我更改副本中的某些内容时,我希望原件保持不变。即,当我从副本中删除 List<MySpecialClass> 中的某些内容时,它保留在原件中的 List<MySpecialClass> 中。

如果我理解正确,这两种方法只创建浅拷贝,这不是我想要的:

 mapCopy = new HashMap<>(originalMap);
mapCopy = (HashMap) originalMap.clone();

我对吗?

有没有比遍历所有键和所有列表项并手动复制更好的方法呢?

原文由 Mathis 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 700
2 个回答

你是对的,浅拷贝不能满足你的要求。它将包含原始地图中的 List s 的副本,但是那些 List s 将引用相同的 List List 对象,以便对对象进行修改 --- 来自一个 HashMap 将出现在相应的 List 来自另一个 HashMap

在 Java 中没有为 HashMap 提供深度复制,因此您仍然必须遍历所有条目和 put 它们在新的 HashMap 但是您还应该每次都制作一份 List 的副本。是这样的:

 public static HashMap<Integer, List<MySpecialClass>> copy(
    HashMap<Integer, List<MySpecialClass>> original)
{
    HashMap<Integer, List<MySpecialClass>> copy = new HashMap<Integer, List<MySpecialClass>>();
    for (Map.Entry<Integer, List<MySpecialClass>> entry : original.entrySet())
    {
        copy.put(entry.getKey(),
           // Or whatever List implementation you'd like here.
           new ArrayList<MySpecialClass>(entry.getValue()));
    }
    return copy;
}

如果你想修改你的个人 MySpecialClass 对象,并且更改不反映在你复制的 List s HashMap 那么你需要制作—它们的新副本也是如此。

原文由 rgettman 发布,翻译遵循 CC BY-SA 3.0 许可协议

不幸的是,这确实需要迭代。但这对于 Java 8 流来说非常简单:

 mapCopy = map.entrySet().stream()
    .collect(Collectors.toMap(e -> e.getKey(), e -> List.copyOf(e.getValue())))

原文由 sprinter 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题