Java HashMap - 深拷贝

19

我只是在尝试找出最佳解决方案,以深度复制HashMap。这个映射中没有实现Cloneable的对象。我希望能找到比序列化和反序列化更好的解决方案。


5
这更像是一个如何克隆无法克隆对象的问题?HashMap似乎是一个可以通过简单递归来解决的小细节。 - Matt Whipple
2
尝试克隆不可克隆的对象是明显的代码异味。现在是考虑重构的好时机。 - amit
2
@Smolda - 如果你不知道对象是什么,那么这很可疑: 你无法保证能够克隆: 如果对象持有一个 transient 属性或一个 stream 等等... - Bruno Grieder
1
有些对象是专门设计的,以便您无法获得它们的多个副本。您 不能 复制任意对象。找到另一种方法。 - Louis Wasserman
可能是将HashMap分配给HashMap的重复问题。 - naXa stands with Ukraine
显示剩余4条评论
3个回答

13

请查看Deep Cloning,在Google Code上你可以找到一个库。你可以在https://github.com/kostaskougios/cloning上阅读它。

它的工作原理很简单。这个库可以克隆任何对象,而且对象不需要实现任何接口,比如Serializable。

Cloner cloner = new Cloner();
MyClass clone = cloner.deepClone(o);
// clone is a deep-clone of o

请注意:这可能会克隆数千个对象(如果克隆的对象具有那么多引用)。此外,复制文件或流可能会导致JVM崩溃。

但是,您可以忽略某些类的实例,例如流等。值得检查此库及其源代码。


它会深度复制对象及其所有嵌套成员吗?比如Object1有Object2,Object2有一个Map<String, Obj3>。当我执行cloner.deepClone(Object1);时,它会深度复制所有内容吗? - zengr
@zengr 是的,它会全部复制。 - stealthjong

3

这并不容易,我们使用某种解决方法:

1)将地图转换为 JSON 字符串。(例如,使用 Google Gson)

2)将 JSON 字符串转换回地图。

请注意,这会影响性能,但这是最简单的方式。


3
我认为这个问题不能以通用的方式实现。
如果有机会,最好采用简单的克隆实现。更复杂一些的方法是创建一个类型映射表,根据每个对象的类查找某种克隆实现类。
当对象可能形成有向无环图时,我通常会保留一个从每个我曾经见过的对象的原始对象到克隆体的映射表,并检查是否已经生成了它。
当你有一个通用图时,问题变得非常棘手。你可能会面临对象创建顺序的奇怪限制,甚至在有final字段时可能是不可能的。
目前,我建议以不那么通用的方式重新编写你的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接