Java的拷贝可以分为三种:浅拷贝(Shallow Copy)、深拷贝(Deep Copy)、延迟拷贝(Lazy Copy)。

在java中除了基本数据类型之外(int,long,short等),还存在引用数据类型,例如String以及对象实例。

对于基本数据类型,实际上是拷贝它的值,而对于引用数据类型,拷贝的就是它的引用,并没有创建一个新的对象,即没有分配新的内存空间。这样的拷贝就称作浅拷贝。

深拷贝就是在引用类型进行拷贝时,创建了新的对象,即分配了新的内存空间给拷贝对象。下面就来具体看看浅拷贝和深拷贝的区别

List浅拷贝

众所周知,list本质上是数组,而数组的是以地址的形式进行存储。

如上图将list A浅拷贝给list B,由于进行的是浅拷贝,所以直接将A的内容复制给了B,java中相同内容的数组指向同一地址,即进行浅拷贝后A与B指向同一地址。造成的后果就是,改变B的同时也会改变A,因为改变B就是改变B所指向地址的内容,由于A也指向同一地址,所以A与B一起改变。

几种浅拷贝

1、遍历循环复制

1 List destList = new ArrayList(srcList.size());2 for(Person p : srcList){3 destList.add(p);4 }

2、使用List实现类的构造方法

List destList = new ArrayList(srcList);

3、使用list.addAll()方法

List destList = new ArrayList();

destList.addAll(srcList);

4、使用System.arraycopy()方法

1 Person[] srcPersons=srcList.toArray(new Person[0]);2 Person[] destPersons=newPerson[srcPersons.length];3 System.arraycopy(srcPersons, 0, destPersons, 0, srcPersons.length);

5、使用Stream的方式copy

List destList = srcList.stream().collect(Collectors.toList());

测试及结果

1 printList(destList); //打印未改变B之前的A

2 srcList.get(0).setAge(100);//改变B

3 printList(destList); //打印改变B后的A4 //打印结果

5 123-->20

6 ABC-->21

7 abc-->22

8 123-->100

9 ABC-->21

10 abc-->22

List深拷贝

如图,深拷贝就是将A复制给B的同时,给B创建新的地址,再将地址A的内容传递到地址B。ListA与ListB内容一致,但是由于所指向的地址不同,所以改变相互不受影响。

深拷贝的方法

1.使用序列化方法

1 /**

2 * 对集合进行深拷贝3 * 注意需要岁泛型类进行序列化(实现serializable)4 *5 *@paramsrc6 *@param7 *@return

8 *@throwsIOException9 *@throwsClassNotFoundException10 */

11 public static List deepCopy(Listsrc) {12 try (ByteArrayOutputStream byteOut = newByteArrayOutputStream();13 ObjectOutputStream outputStream = newObjectOutputStream(byteOut);14 ) {15 outputStream.writeObject(src);16 try (ByteArrayInputStream byteIn = newByteArrayInputStream(byteOut.toByteArray());17 ObjectInputStream inputStream = newObjectInputStream(byteIn);18 ) {19 return (List) inputStream.readObject();20 }21 } catch(Exception e) {22 ThrowableUtils.getString(e);23 }24 returnCollections.emptyList();25 }

2.clone方法

1 public class A implementsCloneable {2 publicString name[];3 public A(){ name=new String[2]; }4 publicObject clone() {5 A o = null;6 try{7 o = (A) super.clone();8 } catch(CloneNotSupportedException e) {9 e.printStackTrace();10 } returno;11 }12 }13

14 for(int i=0;i

Java对对象和基本的数据类型的处理是不一样的。在Java中用对象的作为入口参数的传递则缺省为”引用传递”,也就是说仅仅传递了对象的一个”引用”,这个”引用”的概念同C语言中的指针引用是一样的。当函数体内部对输入变量改变时,实质上就是在对这个对象的直接操作。 除了在函数传值的时候是”引用传递”,在任何用”=”向对象变量赋值的时候都是”引用传递”。

测试及结果

1 printList(destList); //打印未改变B之前的A

2 srcList.get(0).setAge(100);//改变B

3 printList(destList); //打印改变B后的A

4

5 123-->20

6 ABC-->21

7 abc-->22

8 123-->20

9 ABC-->21

10 abc-->22

在浅复制的情况下,源数据被修改破坏之后,使用相同引用指向该数据的目标集合中的对应元素也就发生了相同的变化。因此,在需求要求必须深复制的情况下,要是使用上面提到的方法,请确保List中的T类对象是不易被外部修改和破坏的。

参考:

https://blog.csdn.net/demonliuhui/article/details/54572908

https://blog.csdn.net/fessible_max/article/details/80897670

https://blog.csdn.net/u010648159/article/details/79144154?utm_source=blogxgwz6

java数组深拷贝和浅拷贝_java List复制:浅拷贝与深拷贝相关推荐

  1. java 数组中插入元素_Java数组添加元素

    java 数组中插入元素 How to add elements to an array in java We know that java array size is fixed, so we ca ...

  2. java数组使用实验报告_JAVA数组与类的定义-java实验报告

    JAVA数组与类的定义-java实验报告 JAVA数组与类的定义-java实验报告 .实验目的与要求 1. 熟悉Java类.对象和方法的一般操作练习等. 2. 熟悉数组等的定义和使用. 二.实验内容及 ...

  3. java数组初始化的方式_java数组初始化方式

    在使用一个新的数组之前,要先对其中的数值进行设置,也就是我们常说的初始化工作.因为数组有长度和内容的区分,所以常见的两种初始化方法是动态和静态,另外一种就是默认初始化.下面我们对数组的初始化概念进行理 ...

  4. java 数组声明并初始化_Java数组的声明与初始化

    在<Java数组简介>一节中,我们已经了解了什么是数组.什么是基本数据类型的数组,那么大家是不是迫不及待地想知道一个基本数据类型的数组是什么样子的呢?下面我们就一起来揭开它神秘的面纱吧! ...

  5. java数组声明语句是_Java数组的声明和遍历

    Java 数组 数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同. Java 语言中提供的数组是用来存储固定大小的同类型元素. 你可以声明一个数组变量,如 n ...

  6. java数组转字符串 逗号_java数组与以逗号分隔开的字符串的相互转换操作

    数组转换成以逗号分隔开的字符串 String[] strArray = {"aaa","bbb","ccc"}: String str= S ...

  7. java数组输出是地址_java数组输出 - SuperPcf的个人空间 - OSCHINA - 中文开源技术交流社区...

    java数组输出 输出一个数组中的元素,我们通常用for循环来做,比如: [java] view plaincopy在CODE上查看代码片派生到我的代码片 package test; public c ...

  8. java数组中怎么去重_java数组去重怎么弄???大神来解

    [Java] 纯文本查看 复制代码public class TestDemo { public static void main(String[] args) { //10个整数{9,10,6,6,1 ...

  9. java 数组减除值_java数组操作 - osc_hwpd2zko的个人空间 - OSCHINA - 中文开源技术交流社区...

    什么是数组: 程序 = 算法+数据结构 算法:解决问题的步骤,流程(顺序,分支,循环) 数据结构:将数据按照某种特定的结构来保存 数怎么存 设计良好的,合理的数据结构可以导致好的算法 数组:就是一种最 ...

最新文章

  1. 面对复杂业务架构,阿里架构师是如何做的?(第一期)
  2. 对DbRuleAuthorizationProvider的修改
  3. 有关数组的运算 (sizeof)(strlen)
  4. Android无法运行AVD,android – 无法运行AVD(模拟器)
  5. 开源 一套 Blazor Server 端精致套件
  6. iptables nat实验_【零基础学云计算】LVS负载均衡群集之NAT模式搭建 (实践篇)...
  7. 详解惯性导航论文 RINS-W: Robust Inertial Navigation System on Wheels
  8. Linux系统故障处理案例(一)【转】
  9. ps修改证件照的底色
  10. 香港服务器防攻击能力好吗
  11. 强制卸载 奇安信天擎
  12. doevents raiseevent withevents
  13. 「JavaSE」- 常用类
  14. XCTF-PWN pwn-200(使用DynELF利用write泄露system地址)
  15. Java入门教程(视频)
  16. MAC系统下 U盘\硬盘速度测试工具BlackMagic Disk Speed Test
  17. [Shoi2011]双倍回文
  18. ubuntu 限速 流量监控工具 - iftop
  19. 2006年最受瞩目的七大IT技术
  20. 软件工程(Software Engineering)

热门文章

  1. 1000 驱动_布加迪首款SUV渲染图曝光!采用纯电驱动,马力或将突破1000匹!
  2. MogDB/openGauss 故障排查思路
  3. 下载丨2020 PG亚洲大会(PPT汇总)
  4. pg_basebackup基础备份多表空间
  5. SQL运行速度慢?查查中间件
  6. (又有惊喜)Redis5.0重量级特性Stream尝鲜
  7. 破解class文件的第一步:深入理解JAVA Class文件
  8. LiteOS内核源码分析:消息队列Queue
  9. 基础知识 | 对目标检测认识及理解
  10. 云图说|云上攻击早知道,少不了这个“秘密武器”!