原文地址: https://blog.csdn.net/demonliuhui/article/details/54572908

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.使用序列化方法

public static <T> List<T> deepCopy(List<T> 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);
@SuppressWarnings("unchecked")
List<T> dest = (List<T>) in.readObject();
return dest;
} List<Person> destList=deepCopy(srcList); //调用该方法

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

2.clone方法

public class A implements Cloneable {
public String name[]; public A(){
name=new String[2];
} public Object clone() {
A o = null;
try {
o = (A) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
for(int i=0;i<n;i+=){
copy.add((A)src.get(i).clone());
}

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

测试及结果

printList(destList); //打印未改变B之前的A
srcList.get(0).setAge(100);//改变B
printList(destList); //打印改变B后的A 123-->20
ABC-->21
abc-->22
123-->20
ABC-->21
abc-->22

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

Java小知识----List复制:浅拷贝与深拷贝的更多相关文章

  1. (11.13)Java小知识!

    今天想要与大家分享一下有关于构造方法的知识! 构造方法的定义与作用 构造方法是一种特殊类型的方法.当一个对象被创建的时候,构造方法用来初始化对象,也就是说构造方法其实是一个名词而不是动词,像我刚刚开始 ...

  2. (11.20)Java小知识!

      经过一段时间的学习,我也终于来到了Java语言的核心篇,也就是对象与类的学习,今天想要和大家分享的是关于类的小知识点. 1.类的声明: 类可以看成创建Java对象的模板.类亦可以理解成Java一种 ...

  3. java小知识,驼峰规则

    单词之间不以空格.连接号或者底线连结(例如不应写成:camel case.camel-case或camel_case形式).共有两种格式: 1.小驼峰式命名法(lower camel case): 第 ...

  4. Java小知识----POI事件模式读取Excel 2007

    一.知识背景 1.读取excel的方法选择问题 java中读excel中的时间,我们通常用POI去解析,在使用new HSSFWorkbook(NEW FileInputStream(excelFil ...

  5. Java小知识--length,length(),size()方法详细介绍

    Java中length,length(),size()区别 length属性:用于获取数组长度. eg: int ar[] = new int{1,2,3} /** * 数组用length属性取得长度 ...

  6. JAVA小知识

    eclipse是日蚀的意思,eclipse是IBM公司的,当年和SUN公司的java竞争,sun的意思是太阳,所以你明白了? Java的起名是 java(爪哇)咖啡,java原意是爪哇的意思,当初起名 ...

  7. 每天学点Java小知识【1】

    一 Java标识符和关键字 1.标识符 作用:用来标识类名.变量名.方法名.类型名.数组名.文件名的有效字符序列. 组成规则:由字母.下划线.美元符号和数字组成,且第一个字符不能是数字字符.注意:标识 ...

  8. (10.23)Java小知识!

    ---恢复内容开始--- 方法的定义: 一般情况下,定义一个方法包含以下语法: 修饰符 返回值类型 方法名 (参数类型 参数名 , ...){ ... 方法体 ... return 返回值; } 修饰 ...

  9. (11.06)Java小知识

    最近由于课程变化,学习计划也跟着改动,留给我写博客的时间也越来越少.今天晚上没有课,抽空过来图书馆写一写,许久不写感觉都有点陌生了! 今天要和大季家分享的衔接了上一篇博客,是关于方法的嵌套调用与递归调 ...

随机推荐

  1. CDOJ 1135 邱老师看电影 概率dp

    邱老师看电影 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit St ...

  2. 「美团 CodeM 资格赛」试题泛做

    LibreOJ真是吼啊! 数码 推个式子,把枚举因数转为枚举倍数.然后就发现它是根号分段的.然后每一段算一下就好了. #include <cstdio> #include <cstr ...

  3. ftell函数

    ftell函数用于得到文件位置指针当前位置相对于文件首的偏移字节数,在随机方式存储文件时,由于文件位置频繁的前后移动,程序不容易确定文件的当前位置. /*** a.txt ***/ asd gsder ...

  4. 顺序表应用5:有序顺序表归并(SDUT 3329)

    Problem Description 已知顺序表A与B是两个有序的顺序表,其中存放的数据元素皆为普通整型,将A与B表归并为C表,要求C表包含了A.B表里所有元素,并且C表仍然保持有序. Input ...

  5. Spring——多种方式实现依赖注入

    在Spring的XML配置中,只有一种声明bean的方式:使用<bean>元素并指定class属性.Spring会从这里获取必要的信息来创建bean. 但是,在XML中声明DI时,会有多种 ...

  6. Sql Server 基本使用

    一.登录sql server数据库 1.若需要连接本机数据库服务器,服务器名可以采用“local”.“.”“本机Ip”. 2.在连接sql server 之前,确保sql server服务已经启动,如 ...

  7. AcWing:135. 最大子序和(前缀和 + 单调队列)

    输入一个长度为n的整数序列,从中找出一段长度不超过m的连续子序列,使得子序列中所有数的和最大. 输入格式 第一行输入两个整数n,m. 第二行输入n个数,代表长度为n的整数序列. 同一行数之间用空格隔开 ...

  8. 域名与服务器 ip地址的理解

    域名 服务器 ip地址具有怎样的关系呢 通俗的讲,我们访问一个网站就相当于访问一个服务器的文件,如果想要通过自己的域名来访问一个网站,首先得将域名部署到你的服务器上,然后就可以通过域名访问到你服务器上 ...

  9. 19个JavaScript简化编码小技巧

    这篇文章适合任何一位基于JavaScript开发的开发者.我写这篇文章主要涉及JavaScript中一些简写的代码,帮助大家更好理解一些JavaScript的基础.希望这些代码能从不同的角度帮助你更好 ...

  10. Omnigraffle

    OmniGraffle 7 Mac 注册码 账号:Appked 密码:MFWG-GHEB-HYTW-CGHT-CSXU-QCNC-SXU https://blog.csdn.net/ChibiMaru ...