Java List的深度拷贝方法
为了了解真正的深拷贝是如何实现的,我终于在CSDN博客中找到了通过序列化实现List的深度拷贝的方法
首先简单介绍一下序列化是什么:把对象转换为字节序列的过程称为对象的序列化,反之将字节序列恢复为对象的过程称为对象的反序列化。
JDK类库中的序列化API:java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以 采用默认的序列化方式 。
对象序列化包括如下步骤:
1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;
2) 通过对象输出流的writeObject()方法写对象。
对象反序列化的步骤如下:
1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
2) 通过对象输入流的readObject()方法读取对象。
建立一个Person类,实现Serializable接口
Person下面两个函数写在测试类中
其中函数deepCopy就是利用序列化实现深拷贝,可以看到序列化和反序列化的过程与上文过程相同,不同的地方是,该程序里面用的并非文件输出(输入)流,而是字节数组(ByteArray)输出(输入流),文件输出(输入)流会将转化的字符序列存储在文件中,而字节数组输出(输入)流则是将其保存在一个字节数组的临时变量中,仅占用内存空间,用后会自动清除。
然后再看这里面使用的是List的泛型类,目的就是能够使已经实现Serializable接口的Person类能够被函数所调用然后进行拷贝。
而实现深度拷贝的原理是什么呢?首先已经知道浅拷贝的原因是两个开辟的空间同时指向了同一个顺序表而导致对其中一个进行操作时,另一个也会受到影响。而当把对象序列化并存储后,再将其反序列化(反序列化返回的是一个对象),这时候反序列化得到的对象的存储位置已经与原对象不同了,也就是在反序列化后产生了两个一毛一样的对象,但它们并不是同一个。这时候将用于拷贝的空间用新的对象赋值即可实现深度拷贝。
最后附上测试类和测试结果
测试 运行结果可以看出在对srcList进行修改后,拷贝得到的destList没有发生改变