我的问题是我有一个名为currentComponents
的初始列表。我在另一个名为currentMonitorComponents
的新列表中复制了它的项目。但是,当currentMonitorComponents
中的组件自动修改时,currentComponents
列表中的项目也会被修改。我的代码是这样的---
List<MonitorComponent> currentMonitorComponents = new ArrayList<MonitorComponent>();
currentMonitorComponents.addAll(currentComponents);
答案 0 :(得分:2)
您必须制作清单的深层副本:
ArrayList<MonitorComponent> currentComponentsClone = new ArrayList<MonitorComponent>();
for(MonitorComponent m : currentMonitorComponents)
currentComponentsClone.add(m.clone());
并在您的课程中实施clone
方法:
public class MonitorComponent{
String s;
Date d;
...
public MonitorComponent clone(){
MonitorComponent m = new MonitorComponent();
m.s = this.s.clone();
m.d = this.d.clone();
...
return m;
}
}
答案 1 :(得分:1)
最后这两个元素都有相同的元素(MonitorComponent)..它们指向内存中的相同对象。你必须克隆列表中的每个MonitorComponent ..
您需要迭代这些项目,并逐个克隆它们,然后将克隆放入结果arraylist中。
public static List<MonitorComponent> cloneList(List<MonitorComponent> list) {
List<MonitorComponent> clone = new ArrayList<MonitorComponent>(list.size());
for(MonitorComponent item: list) clone.add(item.clone());
return clone;
}
为了实现这一点,显然,您必须让MonitorComponent对象实现Cloneable接口和clone()方法。
答案 2 :(得分:0)
您正在做的是创建一个浅表副本。您有一个新列表,但元素是相同的对象,而不是对象的副本。因此,如果您修改其中一个对象,则可以通过两个列表查看更改。
您也可以通过为新列表创建新对象来创建深层(呃)副本,这些对象是第一个列表中对象的副本。您要做的确切取决于相关对象的类型。一种选择可能是使用clone()
。另一种可能是调用复制构造函数。您需要对原始列表的每个元素执行此操作,并将副本添加到新列表中。
答案 3 :(得分:0)
当您将元素从原始列表“复制”到新列表时,您实际上是复制原始列表中包含的引用,而不是原始列表中的实际对象。因此,每个列表中的第一个元素确实指向相同的底层对象;因此,当您使用一个列表更改该对象时,另一个列表会看到更改。这有点像对相同的基础系列对象有两个“视图”。
要解决此问题,您需要从原始列表中“克隆”要复制的每个对象。有几种方法可以做到这一点,但最后您必须确保在代码中的某个时刻使用new
关键字,clone()
被调用(clone()
方法在Java中,从我被告知的,应该避免),或者调用构造函数。这可以确保您放入第二个列表的对象与原始文件不同。