List<Person> b = null;
List<Person> a = new ArrayList<Person>();
a.add(new Person("Jack",2));
a.add(new Person("Tom",2));
b = (ArrayList<Person>)((ArrayList<Person>)a).clone();//浅复制
b = new ArrayList<Person>(a);//浅复制
b = new ArrayList();//浅复制
b.addAll(a);
Collections.copy(b,a);//浅复制
System.arraycopy(a,0,b,0,a.size());//浅复制
try{
b = deepCopy(a);//深复制
}catch (Exception e){
//do something
}
System.out.println(b==a);
System.out.println(b.equals(a));
b.get(0).setName("Kate");
System.out.println(a.get(0).getName());
}
public static <T extends Serializable> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(src);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in =new ObjectInputStream(byteIn);
List<T> dest = (List)in.readObject();
return dest;
}
Person类,拥有名字和年龄属性及其相关的get,set方法,详细代码略。
以上部分为伪代码,从输出结果可以看出,如果输出是Kate则是浅复制,Jack则是深复制。因为,在浅复制的情况下,源数据被修改破坏之后,使用相同引用指向该数据的目标集合中的对应元素也就发生了相同的变化。因此,在需求要求必须深复制的情况下,要是使用上面提到的方法,请确保List<T>中的T类对象是不易被外部修改和破坏的。
其实,有时候浅复制也可以"当作"深复制用,关键看类是否提供了破坏数据的方法(如Person类的setter方法修改属性,而String则不能修改字符串的内容)。如果把以上Person类换成String,会有意外的"深复制"效果。