ArrayList深拷贝的一种实现方法

时间:2021-08-04 19:53:45

大家应该理解浅拷贝和深拷贝的区别:

浅拷贝:被复制对象的任何变量都含有和原来的对象相同的值,而任何的对其他对象的引用仍然指向原来的对象。对拷贝后的引用的修改,还能影响原来的对象。

深拷贝:把要复制的对象所引用的对象都复制了一遍,对现在对象的修改不会影响原有的对象。

如果大家还不理解,在网上看到一个人的比喻很有意思:

就好比一个爸爸一个儿子 
浅拷贝:你克隆一下,只得到一个爸爸,这是浅 
深拷贝:你克隆一下,既得到了爸爸,又得到了儿子,这是深 
另外,如果你克隆的对象里面还包括其他对象,比如汽车对象里还有座位对象,那么浅的结果就是汽车被拷贝了,座位并没有,深的话,就是一起都拷贝了。

下面,给大家说一下如何实现ArrayList的深拷贝的一种实现方式:

有一个类Userinfo,需要实现Serializable接口,可以序列化。

import java.io.Serializable;   

public class Userinfo implements Serializable
{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

}



下面是我的一个测试类:
package test;   

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public class TestMain {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
List src = new ArrayList(2);
Userinfo ui1 = new Userinfo();
ui1.setId(1);
ui1.setName("aaa");
src.add(ui1);

Userinfo ui2 = new Userinfo();
ui1.setId(2);
ui1.setName("bbb");
src.add(ui2);

List dest = new ArrayList(2);

TestMain test = new TestMain();

try {
dest = test.deepCopy(src);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


System.out.println(src==dest);
Userinfo u = (Userinfo)src.get(0);
Userinfo uu = (Userinfo)dest.get(0);
uu.setName("dkkdkddk");
System.out.println(u.getName());

System.out.println(uu.getName());

}

public List deepCopy(List 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 dest = (List)in.readObject();
return dest;
}
}


就是把ArrayList的原来的对象进行序列化,然后通过反序列化读取出来,就可以了。

当然,记着放到集合中的元素也要能够序列化,所以必须实现Serializable接口。

在此,也欢迎大家提出其它的ArrayList深拷贝实现方法。



//------------------------------------------------------------------------------------------------------------

List list1 = new ArrayList();
List list2 = new ArrayList(list1);
这种方式达不到深拷贝的。