如何制作Java ArrayList的深层副本

66

可能是重复问题:
如何克隆一个ArrayList并且也克隆其内容?

我正在尝试复制一个ArrayList。底层对象很简单,只包含字符串、整数、BigDecimal、日期和DateTime对象。 如何确保对新ArrayList所做的修改不会反映在旧ArrayList中?

Person morts = new Person("whateva");

List<Person> oldList = new ArrayList<Person>();
oldList.add(morts);
oldList.get(0).setName("Mortimer");

List<Person> newList = new ArrayList<Person>();
newList.addAll(oldList);

newList.get(0).setName("Rupert");

System.out.println("oldName : " + oldList.get(0).getName());
System.out.println("newName : " + newList.get(0).getName());

祝福, P


Java是按引用传递的。因此,最初在两个列表中都有“相同”的对象引用...您需要使用clone()方法。据我所知,您必须对每个项目单独调用它。 - PhD
2个回答

35

在添加对象之前进行克隆。例如,使用newList.addAll(oldList);的替代方法。

for(Person p : oldList) {
    newList.add(p.clone());
}

假设Person类中正确地重写了clone方法。


是的,clone() 是浅拷贝,拷贝后 Person 对象中的成员仍然是同一个引用,因此您需要根据自己的需求重写 clone 方法。 - Y.L.
没有覆盖的假设,默认的 clone() 是受保护的。 - Adeel Ahmad

25
public class Person{

    String s;
    Date d;
    ...

    public Person clone(){
        Person p = new Person();
        p.s = this.s.clone();
        p.d = this.d.clone();
        ...
        return p;
    }
}

在你的执行代码中:

ArrayList<Person> clone = new ArrayList<Person>();
for(Person p : originalList)
    clone.add(p.clone());

33
Java中的String不是原始数据类型。 - ataulm
8
在Java中,字符串是不可变的。由于您无法更改它们,因此克隆它们是没有意义的。 - Donal Lafferty
16
“there's no point in cloning”与“ You can't clone”不同。 - ataulm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接