arraylist的副本不断修改为原始值

时间:2013-02-07 02:16:26

标签: java arraylist copy duplicates clone

我正在研究一个用于保存和调用屏幕状态的系统,这是我第一次搞乱这种东西,所以我不确定最好的方法是什么,但我目前存储所有的数组列表中的“PreviewMonitor”对象(大约40个左右)。问题在于,当我创建一个名为“allPreviewMonitors”的ArrayList副本时,我最终得到一个ArrayList,其元素随着原始元素的更新而不断变化。这几乎就像我正在使用原始的ArrayList,事实上,当我创建allPreviewMonitors的副本时,它应该是一个完全不同的ArrayList,其中包含元素的“冻结”版本及其状态。为什么会发生这种情况?如果需要,我可以显示代码,但我不确定这里是否需要。

4 个答案:

答案 0 :(得分:4)

Arraylist与所有Collections一样,仅包含对象的引用。 复制List是不够的,你还必须在创建List的副本时克隆()列表中的元素(或创建新元素,或使用复制构造函数)。

这称为“深拷贝”,而您目前有“浅拷贝”。

答案 1 :(得分:3)

您只是将对象引用复制到ArrayList中。您需要自己复制对象。

在Java中,所有对象变量实际上都是引用变量。所以代码:

Myclass myObject = new Myclass();
Myclass otherObject = myObject;

创建一个Myclass对象,并在引用变量myObject中存储对该Myclass对象的引用。然后,它创建一个新的引用变量otherObject,并将引用数据(例如内存地址)从myObject复制到otherObject。这些现在引用内存中的相同对象。此时,该行

myObject.myMethod();

的结果相同
otherObject.myMethod();

您在ArrayList中获得的是对相同对象的不同引用。 你想要的是以下之一:

Myclass otherObject = myObject.clone(); // use the clone function
// OR
Myclass otherObject = new Myclass(myObject); // use a copy constructor

如果使用clone()或复制构造函数将对象放入ArrayList,则ArrayList将包含对相同副本的引用,而不是对相同副本的引用。

正如其他人所指出的那样,只是制作参考文献的副本称为“浅版本”,而将所引用的对象的副本称为“深层副本”

答案 2 :(得分:2)

您需要确保执行“深层复制” - 即克隆PreviewMonitor对象。默认情况下,您只需执行浅拷贝并复制对同一对象的引用。

答案 3 :(得分:0)

要克隆,您不能只返回当前对象。您必须使用与当前对象相同的值创建新对象。换句话说,使用当前对象的Class的构造函数并创建一个新对象。确保旧对象和新对象之间的属性匹配。返回新对象并对原始列表中的每个对象重复。