java中List的浅拷贝与深拷贝
List浅拷贝
众所周知,list本质上是数组,而数组的是以地址的形式进行存储。

如上图将list A浅拷贝给list B,由于进行的是浅拷贝,所以直接将A的内容复制给了B,java中相同内容的数组指向同一地址,即进行浅拷贝后A与B指向同一地址。
造成的后果就是,改变B的同时也会改变A,因为改变B就是改变B所指向地址的内容,由于A也指向同一地址,所以A与B一起改变。
几种浅拷贝
1、遍历循环复制
List<Person> destList=new ArrayList<Person>(srcList.size());
for(Person p : srcList){
destList.add(p);
}
2、使用List实现类的构造方法
List<Person> destList=new ArrayList<Person>(srcList);
3、使用list.addAll()方法
List<Person> destList=new ArrayList<Person>();
destList.addAll(srcList);
4、使用System.arraycopy()方法
Person[] srcPersons=srcList.toArray(new Person[0]);
Person[] destPersons=new Person[srcPersons.length];
System.arraycopy(srcPersons, 0, destPersons, 0, srcPersons.length);
测试及结果
printList(destList); //打印未改变B之前的A
srcList.get(0).setAge(100);//改变B
printList(destList); //打印改变B后的A //打印结果
123-->20
ABC-->21
abc-->22
123-->100
ABC-->21
abc-->22
List深拷贝

如图,深拷贝就是将A复制给B的同时,给B创建新的地址,再将地址A的内容传递到地址B。ListA与ListB内容一致,但是由于所指向的地址不同,所以改变相互不受影响。
深拷贝的方法
1.利用CollectionUtils的mergeArrayIntoCollection和Collections.copy结合实现深拷贝
public class TechSysVo {
@Getter
@Setter
private Long id;
@Getter
@Setter
private String name;
public TechSysVo() {
}
}
import com.wsh.clone.arraylist.TechSysVo;
import org.springframework.util.CollectionUtils; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; public class App { public static void main(String[] args) {
TechSysVo techSysVo = new TechSysVo();
TechSysVo techSysVo1 = new TechSysVo();
List<TechSysVo> list = new ArrayList<>();
list.add(techSysVo);
list.add(techSysVo1);
//list深度拷贝
List<TechSysVo> newList = new ArrayList<>();
CollectionUtils.mergeArrayIntoCollection(new Object[list.size()],newList);
Collections.copy(newList, list);
//拷贝完清空result
list.clear();
System.out.println(list.toString());
System.out.println(newList.toString()); } }
2.使用序列化方法
public class TechSysVo implements Serializable {
@Getter
@Setter
private Long id;
@Getter
@Setter
private String name;
public TechSysVo() {
}
}
public static <T> List<T> deepCopy(List<T> src) {
try {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(src);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in = new ObjectInputStream(byteIn);
@SuppressWarnings("unchecked")
List<T> dest = (List<T>) in.readObject();
return dest;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
TechSysVo techSysVo = new TechSysVo();
TechSysVo techSysVo1 = new TechSysVo();
List<TechSysVo> list = new ArrayList<>();
list.add(techSysVo);
list.add(techSysVo1);
//list深度拷贝
List<TechSysVo> newList = new ArrayList<>();
newList = deepCopy(list);
//拷贝完清空result
list.clear();
System.out.println(list.toString());
System.out.println(newList.toString());
}
3.使用Java8的新特性的Stream实现深拷贝
public static void main(String[] args) {
TechSysVo techSysVo = new TechSysVo();
TechSysVo techSysVo1 = new TechSysVo();
List<TechSysVo> list = new ArrayList<>();
list.add(techSysVo);
list.add(techSysVo1);
//list深度拷贝
List<TechSysVo> newList = list.stream().collect(Collectors.toList());
//拷贝完清空result
list.clear();
System.out.println(list.toString());
System.out.println(newList.toString());
}
在浅复制的情况下,源数据被修改破坏之后,使用相同引用指向该数据的目标集合中的对应元素也就发生了相同的变化。
因此,在需求要求必须深复制的情况下,要是使用上面提到的方法,请确保List中的T类对象是不易被外部修改和破坏的。
java中List的浅拷贝与深拷贝的更多相关文章
- Java中的Cloneable接口与深拷贝、浅拷贝
Cloneable接口是一个标记接口,也就是没有任何内容,定义如下: 这里分析一下这个接口的用法,clone方法是在Object种定义的,而且是protected型的,只有实现了这个接口,才可以在该类 ...
- java List复制:浅拷贝与深拷贝
Java的拷贝可以分为三种:浅拷贝(Shallow Copy).深拷贝(Deep Copy).延迟拷贝(Lazy Copy). 在java中除了基本数据类型之外(int,long,short等),还存 ...
- 一文搞懂Java引用拷贝、浅拷贝、深拷贝
微信搜一搜 「bigsai」 专注于Java和数据结构与算法的铁铁 文章收录在github/bigsai-algorithm 在开发.刷题.面试中,我们可能会遇到将一个对象的属性赋值到另一个对象的情况 ...
- 关于python中赋值、浅拷贝、深拷贝之间区别的深入分析
当重新学习了计算机基础课程<数据结构和算法分析>后再来看这篇自己以前写的博文,发现错误百出.python内置数据类型之所以会有这些特性,归根结底是它采用的是传递内存地址的方式,而不是传递真 ...
- Python中赋值、浅拷贝与深拷贝
python中关于对象复制有三种类型的使用方式,赋值.浅拷贝与深拷贝.他们既有区别又有联系,刚好最近碰到这一类的问题,研究下. 一.赋值 在python中,对象的赋值就是简单的对象引用,这点和C++不 ...
- python中赋值、浅拷贝、深拷贝详解(转)
一.赋值 >>> a = [1, 2, 3]>>> b = a>>> print(id(a), id(b), sep='\n')139701469 ...
- Python中赋值、浅拷贝和深拷贝的区别
前言文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取http: ...
- JAVA中对象的克隆及深拷贝和浅拷贝
使用场景: 在日常的编程过程 中,经常会遇到,有一个对象OA,在某一时间点OA中已经包含了一些有效值 ,此时可能会需一个和OA完全相对的新对象OB,并且要在后面的操作中对OB的任何改动都不会影响到OA ...
- 图解python中赋值、浅拷贝、深拷贝的区别
Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果.下面本文就通过简单的例子介绍一下这些概念之间的差别. 对象赋值 直接看一段代码: will = ...
- java的clone()、浅拷贝与深拷贝
clone()方法是Object的native方法.protected native Object clone() throws CloneNotSupportedException; 声明为pro ...
随机推荐
- 低版本客户端连接高版本数据库报错ORA-28040、ORA-01017
测试环境: 客户端:Oracle 11.2.0.1 服务端:Oracle 19.16 测试过程: 1.低版本客户端连接高版本数据库报错ORA-28040 2.低版本客户端连接高版本数据库报错ORA-0 ...
- APP测试注意点-安装卸载与运行
1.安装和卸载 应用在不同系统版本的ios和android是否可以正常安装(适配问题) 安装过程中是否可以取消 手机存储空间不足时安装应用是否有相应提示信息 安装后的应用是否可以正常卸载 卸载后是否会 ...
- 《Terraform 101 从入门到实践》 第五章 HCL语法
<Terraform 101 从入门到实践>这本小册在南瓜慢说官方网站和GitHub两个地方同步更新,书中的示例代码也是放在GitHub上,方便大家参考查看. 介绍了Terraform一些 ...
- 尊重 respect
尊重他人,这里面的门道. 明面上尊重他人要在自身有地位有身份的前提下,你身边的其他人 才能高效接收到你传递的信号,这叫礼贤下士. 暂时没地位的人更是应该无时无刻释放出尊重他人的信号,来向外界传达你是一 ...
- 谈谈Selenium中的三种切换之alert
谈谈Selenium中的三种切换之alert 一.如何识别 识别方法:alert中的确定.取消.输入框无法用inspector定位到,当然还有一些特例. alert分为三种 alert confirm ...
- jmeter做性能测试
一.线程与进程 一个软件/程序,是以进程的方式存在的,一个进程可含多个线程(一个软件可以做多个事情,就是基于线程而实现的) 二.并发的基本概念 并发: 并发用户数:同一时刻,服务器/接口接收到的用户量 ...
- appium 在linux安装和使用(持续更新)
appium V1.10 centos7.4 安装 安装步骤 1. 安装node 为了得到npm(node package manager,nodejs的安装包管理工具,可以通过npm来下载appiu ...
- C++梳理
1.基础篇 1.C++ 中的四种智能指针 为什么要使⽤智能指针:智能指针其作⽤是管理⼀个指针,避免程序员申请的空间在函数结束时忘记释放,造成内存泄漏这种情况的发⽣.使⽤智能指针可以很⼤程度上的避免这个 ...
- ubuntu 一键安装lnmp环境
转载csdn: ubuntu 一键安装lnmp环境_手艺人小在的博客-CSDN博客 注意:采用编译安装方法,花费时间较长,这个只有稳定版的,没有高版本的. 转载vpsgo: Linux上一键安装LNM ...
- ArcGIS for Android 开发环境搭建
ArcGIS for Android 开发环境搭建 1. 基础环境搭建 1.1. 安装JDK 安装JDK8,并设置环境变量 在cmd窗口输入java -version检查是否配置完成 java -ve ...