原文地址: 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. ASCII和UTF-8

    造冰箱的熊猫@cnblogs 2018/12/11 用了这么久的UTF-8,第一次了解了点UTF-8的细节 UTF-8[1]属于变长度编码.一个UTF-8字符的编码长度为1~4个字节. 1)长度为1个 ...

  2. TCP连接创建与终止

    创建连接:三次握手一句话,”就是客户端发个syn,服务端发个syn+ack,客户端再回个ack“ 终止连接:四次挥手

  3. jQuery事件之一次性事件

    语法: $(selector).one(type, data, callback) 作用: (1)为每一个匹配元素的特定事件(比如click)绑定一个一次性的事件处理函数. (2)每个对象上,这个事件 ...

  4. Travis-CI自动化测试并部署至自己的CentOS服务器

    一直都想自己部署一下自动化测试部署,在了解了Travis-CI之后终于准备在这次和小伙伴一起做的一个博客类网站实验下了. 因为这是一个前后端分离的项目,所以我这里只管前端工程的自动化部署,前端主要用V ...

  5. window7上爬虫框架Scrapy的安装 --错误分析lxml

    本文讲解的是python已经安装成功的情况下,且pip可以使用 版本:python2.7.10 #安装 pip install Scrapy 在安装Scrapy框架时总会报lxml安装不了的各种错误, ...

  6. 如何实现一个串行promise

    异步执行任务A.B.C,...... 1.使用数组的reduce方法,reduce里有四个参数,pre,next,index,arr, 2.如果then方法里返回的是一个promise对象,那么执行下 ...

  7. kettle的数据库配置的表分析

    以下场景,用mysql来举例说明.本文是在初步了解了kettle的数据库配置之后,做的总结和分析.将kettle中的配置用数据库管理的时候,在创建了一个新的数据库,还没有做任何kettle中的job和 ...

  8. LC 650. 2 Keys Keyboard

    Initially on a notepad only one character 'A' is present. You can perform two operations on this not ...

  9. 加密算法之 MD5算法

    题记:本人自测了很多次,该算法和apache的commons utils包中的MD5算法计算一致 一.针对文件内容生成MD5值 应用场景:针对文件,在传输过程由于网络原因丢帧或者被人别恶意篡改内容,可 ...

  10. 学习前端第一天心得体会(初步了解HTML5的新特性以及和HTML的区别)

    一.HTML5是什么? HTML5 是最新的 HTML 标准. HTML5 是专门为承载丰富的 web 内容而设计的,并且无需额外插件. HTML5 拥有新的语义.图形以及多媒体元素. HTML5 提 ...