1

Suppose I have following structure and I created a list like this. If I do temp.remove(0) it won't affect on the original list but temp.get(0).vars.remove(0) will remove elements from the original list too.

I think new ArrayList(top.mids) is not doing a deep copy then how come temp.remove(0) doesn't affect on the original list?

//Top class init part and adding elements are omitted
List<Mid> temp = new ArrayList(top.mids);
temp.remove(0);
temp.get(0).bots.remove(0);


public class Top{
    List<Mid> mids = new ArrayList<Mid>();
}

public class Mid{
    List<Bot> bots = new ArrayList<Bot>();

}

public class Bot{
    int id; 
}
4

2 回答 2

4

是的,你的理解是正确的。 List newList = new ArrayList(collection);会做一个浅拷贝。您可以在newList不影响原始的情况下修改collection,但它们都将引用相同的元素,因此如果您修改一个列表中的一个元素,另一个列表的元素也会得到更改。

这称为浅拷贝。这是我所描述的内容的视觉表示:

在此处输入图像描述

底部的东西是数组中的对象。

于 2013-08-28T21:38:17.693 回答
1

该声明

new ArrayList(top.mids) 没有做深拷贝

指的是虽然您确实有一个包含旧列表中所有项目的新列表,但新列表中的项目与旧列表引用的内存中的实例相同。

这意味着虽然您可以修改新列表的内容(即对对象的引用)而不会对旧列表产生任何影响,但通过旧列表访问它们时,修改该列表中的对象也将是可见的。

为了说明这一点,我想举一个例子:

List<X> oldList = Arrays.asList(new X("1"), new X("2"));
List<X> newList = new ArrayList<X>(oldList);

newList.remove(0);
System.out.println(newList.size()); // Prints 1
System.out.println(oldList.size()); // Prints 2

System.out.println(oldList.get(1).getValue()); // Prints 2
newList.get(0).setValue("3");
System.out.println(oldList.get(1).getValue()); // Prints 3
于 2013-08-28T21:38:21.970 回答