【发布时间】:2010-07-20 15:48:04
【问题描述】:
我想制作一些 Object[] 和 ArrayList 的深拷贝 我该怎么做(没有循环和调用克隆)
没有执行此操作的标准工具吗?
谢谢 若昂
【问题讨论】:
-
深拷贝会有某种概念循环。问题是它是否隐藏在 util 中。
-
要修改副本吗?
我想制作一些 Object[] 和 ArrayList 的深拷贝 我该怎么做(没有循环和调用克隆)
没有执行此操作的标准工具吗?
谢谢 若昂
【问题讨论】:
没有琐碎的对象需要提供一些来支持复制:即使那是以实现克隆或序列化的形式。这或多或少是为什么没有内置方法并且循环不可避免的原因。
如果这都是你自己的代码,那么我会推荐一个复制构造函数而不是克隆或序列化/反序列化,因为这更 OO;您要求对象创建自己的副本,而不是要求 JVM 进行低级复制。这样的代码非常简单易读,因此希望从长远来看维护成本更低:
public class Widget {
private int x = 0;
public Widget(Widget copyMe){
this.x = copyMe.x;
// ...
}
// ....
}
当然,您仍然需要一个循环来遍历旧集合,调用复制构造函数来填充新集合。有一本书名为 Effective Java,其中详细介绍了克隆和序列化的陷阱,我强烈推荐。
有些系统确实需要非常高速的复制和排序等(例如 Hadoop)。这样的系统让开发人员有责任支持自定义二进制格式(例如 byte[] getAsBytes() / public Widget(byte[] fromBytes) )。将许多转换为 byte[] 的对象打包到一个更大的数组中意味着可以在大数组上使用 System.arraycopy 非常快速地一次复制它们。 JVM 将 System.arraycopy 作为低级内存复制。您仍然需要循环从复制后的字节块中反序列化对象。
一般来说,编译器和 jvm 倾向于很好地优化基本代码,所以除非你实际测量出你有一个真实且可测量的性能问题,否则一个非常简单的循环和一个非常易读的复制构造函数将是最好的长期方法.
【讨论】:
您可以序列化整个数组,然后将其反序列化为一个新变量。这有效地进行了深层复制。
否则你将不得不自己实现一个深拷贝。
【讨论】: