我正在尝试克隆MyGraph的一个对象,我希望它是一个深层复制,因此对象内的arraylists也被克隆.现在我有:
public static MyGraph deepCopy(MyGraph G){
MyGraph Copy = (MyGraph) G.clone();
Copy.VertexG = (ArrayList<Integer>) G.VertexG.clone();
Copy.EdgeG = (ArrayList<String>) G.EdgeG.clone();
return Copy;
}
Run Code Online (Sandbox Code Playgroud)
这会在尝试克隆arraylist时返回错误.我不确定这是否是将arraylists添加到对象的正确方法.
clone中的操作返回ArrayList对象的浅表副本,并且不适合您的目的。手动解决方法是:
clone显然,只有当数组列表包含实现 的项目,并且项目clone操作实际上返回深层副本时,这才有效。换句话说,它不能保证。实际上,为 Java 对象实现深度克隆功能并不容易,请参阅Java 中的广泛讨论:深度克隆/复制实例和其他 SO 线程的推荐解决方案,以了解可用的选项。除了那里提供的答案之外,这里还有一些其他选项:
如果层次结构中的所有(必需的)对象都可以序列化,那么您可以使用以下简单的代码进行深度克隆:
public MyGraph deepCopy() {
try {
final ByteArrayOutputStream baos = new ByteArrayOutputStream(256);
final ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
oos.close();
final ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(baos.toByteArray()));
final MyGraph clone = (QuicksortTest) ois.readObject();
return clone;
} catch (final Exception e) {
throw new RuntimeException("Cloning failed");
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,一些深度克隆库将标准 Java 序列化与反射黑客和/或字节码检测相结合,以使整个对象层次结构完全可序列化。您可能需要,也可能不需要。
例如,Dozer,提供快速深度复制功能。Orika也可以实现相同的目的,尽管配置更多:
public MyGraph deepCopy() {
final DozerBeanMapper mapper = new DozerBeanMapper();
final QuicksortTest clone = mapper.map(this, MyGraph.class);
return clone;
}
Run Code Online (Sandbox Code Playgroud)
当然,唯一的缺点是您需要将额外的依赖项引入项目中。
总而言之,你的deepCopy方法不应该是静态的。另外,您应该认真考虑通过将对象设为私有并实现 getter/setter 来封装对象的状态。
| 归档时间: |
|
| 查看次数: |
9891 次 |
| 最近记录: |