前言

今天在项目中使用集合类List的时候发生了一个异常:java.util.ConcurrentModificationException,so,百度一番,此异常的大致意思是在遍历一个list的时候,这个list被修改了,wft???看到这个表示一脸的黑人问号,先说说我的使用场景,有一个很长的list保存所有数据,然后将此list使用List.subList()方法分割成相同长度的多个小list进行使用,当我更新数据的时候,就出现了这个异常,检查发现,是在遍历总list的时候同时在刷新分割出来的小list,所以出现了异常。

深拷贝/浅拷贝

如果学过C语言,那么很容易理解这两个概念,深拷贝就是将指定地址的数据拷贝出来,浅拷贝只是将需要拷贝的数据的地址复制了一份而已。

举个栗子:

在你桌面上有一个txt文件,然后你对他创建了一个快捷方式,就是浅拷贝,你直接复制了这个txt,就是深拷贝,两者的区别就是,通过浅拷贝,就是公用一个数据(点击快捷方式打开的txt文件还是原来的那个),你可能无形中改变了原来的数据,深拷贝就是自己有了一个完全相同数据,改变这个不会影响原来的数据。浅拷贝比较快,深拷贝比较慢,自己类比大文件的复制和创建快捷方式的速度。

再举个栗子

上面都是理论的,要想理解,必须read the fucking sourcecode!!!

可以看到,浅拷贝的”内存地址”(java的对象的hashCode类似于内存地址)和原始数据相同,而且修改了会影响原来的数据!!!

最后补上我们的实体类。

探究下List的subList操作是不是浅拷贝

下面是测试代码以及输出结果,可以很清楚看到,subList是浅拷贝!!!!关于list的其他方法大家可以自行测试,其实大多数都是浅拷贝(为了速度).

深拷贝方法

由于java里面没有C语言中的memcpy函数,所以深拷贝只能通过对象的序列化和反序列化来进行,代码如下。需要注意的是List<T>里面的数据必须都能序列化.(实现Serializable接口即可),注意:此方法效率比较低,对于要求快速处理,需短时间多次拷贝的慎用!!!!

最后修改日期: 2017年1月10日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。