如果修改了重复列表,则会修改初始列表

时间:2014-04-29 06:39:40

标签: java list

我的问题是我有一个名为currentComponents的初始列表。我在另一个名为currentMonitorComponents的新列表中复制了它的项目。但是,当currentMonitorComponents中的组件自动修改时,currentComponents列表中的项目也会被修改。我的代码是这样的---

 List<MonitorComponent> currentMonitorComponents = new ArrayList<MonitorComponent>();
        currentMonitorComponents.addAll(currentComponents);

4 个答案:

答案 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中,从我被告知的,应该避免),或者调用构造函数。这可以确保您放入第二个列表的对象与原始文件不同。