Java小知识----List复制:浅拷贝与深拷贝
原文地址: 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复制:浅拷贝与深拷贝的更多相关文章
- (11.13)Java小知识!
今天想要与大家分享一下有关于构造方法的知识! 构造方法的定义与作用 构造方法是一种特殊类型的方法.当一个对象被创建的时候,构造方法用来初始化对象,也就是说构造方法其实是一个名词而不是动词,像我刚刚开始 ...
- (11.20)Java小知识!
经过一段时间的学习,我也终于来到了Java语言的核心篇,也就是对象与类的学习,今天想要和大家分享的是关于类的小知识点. 1.类的声明: 类可以看成创建Java对象的模板.类亦可以理解成Java一种 ...
- java小知识,驼峰规则
单词之间不以空格.连接号或者底线连结(例如不应写成:camel case.camel-case或camel_case形式).共有两种格式: 1.小驼峰式命名法(lower camel case): 第 ...
- Java小知识----POI事件模式读取Excel 2007
一.知识背景 1.读取excel的方法选择问题 java中读excel中的时间,我们通常用POI去解析,在使用new HSSFWorkbook(NEW FileInputStream(excelFil ...
- Java小知识--length,length(),size()方法详细介绍
Java中length,length(),size()区别 length属性:用于获取数组长度. eg: int ar[] = new int{1,2,3} /** * 数组用length属性取得长度 ...
- JAVA小知识
eclipse是日蚀的意思,eclipse是IBM公司的,当年和SUN公司的java竞争,sun的意思是太阳,所以你明白了? Java的起名是 java(爪哇)咖啡,java原意是爪哇的意思,当初起名 ...
- 每天学点Java小知识【1】
一 Java标识符和关键字 1.标识符 作用:用来标识类名.变量名.方法名.类型名.数组名.文件名的有效字符序列. 组成规则:由字母.下划线.美元符号和数字组成,且第一个字符不能是数字字符.注意:标识 ...
- (10.23)Java小知识!
---恢复内容开始--- 方法的定义: 一般情况下,定义一个方法包含以下语法: 修饰符 返回值类型 方法名 (参数类型 参数名 , ...){ ... 方法体 ... return 返回值; } 修饰 ...
- (11.06)Java小知识
最近由于课程变化,学习计划也跟着改动,留给我写博客的时间也越来越少.今天晚上没有课,抽空过来图书馆写一写,许久不写感觉都有点陌生了! 今天要和大季家分享的衔接了上一篇博客,是关于方法的嵌套调用与递归调 ...
随机推荐
- web上传整个文件夹
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 先说下要求: PC端全平台支持,要求支持Windows,Mac,Linux 支持所 ...
- Linux环境下软件安装
下载——解压缩: 把得到的目录放到一个不碍事的目录,我们可以设置隐藏目录: 查看可执行程序: 如何变成系统命令? PATH:一个可执行程序只要放到这些目录中任何一个就可以,就可以变成系统识别的命令,当 ...
- MapBox
MapBox的地图API大家用过吗 用作网站或者APP的底图,就不用自己架设地图服务器了 发布自己的地图了 这跟Google Map是一样的道理,类似的还有天地图,高德,百度地图API等等. 属于前端 ...
- Codeforces 514 D R2D2 and Droid Army(Trie树)
题目链接 大意是判断所给字符串组中是否存在与查询串仅一字符之差的字符串. 关于字符串查询的题,可以用字典树(Trie树)来解,第一次接触,做个小记.在查询时按题目要求进行查询. 代码: #define ...
- 简单的SSRF的学习
自己眼中的SSRF 成因 服务端允许了 可以向其他服务器请求获取一些数据 通过各种协议 http https file等(外网服务器所在的内网进行端口的扫描指纹的识别等) 一SSRF配合redis未授 ...
- Scrapy 设置随机 User-Agent
方式一:在每个 Spider中设置(针对单个Spider) class TencentSpider(scrapy.Spider): name = 'tencent' allowed_domains = ...
- Vue-1:鄙人是如何开始学习的
说实话,Vue这个东西早想学习她了.为啥呢?不是因为有多火热多好用多水嫩...而是每次面试都会问我,你会不会Vue...接下来就是突然安静的空气,,,真TM气人.所以鄙人在经历诸事之后决心一定要搞一下 ...
- hibernate映射配置
1. 普通字段类型 2. 主键映射 单列主键映射 多列作为主键映射 主键生成策略,查看api: 5.1.2.2.1. Various additional generators 数据库: Q:一个 ...
- JDBC插入数据,获取自增长值
package com.loaderman.demo.c_auto; public class Dept { private int id; private String deptName; publ ...
- ServiceStatusUtils判断服务是否运行
import android.app.ActivityManager; import android.app.Service; import android.content.Context; impo ...