转载---Java集合对象的深度复制与普通复制
原博文:http://blog.csdn.net/qq_29329775/article/details/49516247
最近在做算法作业时出现了错误,原因是没有弄清楚java集合的深度复制和浅度复制的区别。
1.首先是对Java集合对象得浅复制与深度复制的理解
普通的集合复制只是将内存中栈的地址快拷贝一份,使得一个新的集合对象指向这个地址块,但是集合中的对象变量却是指向堆中的同一块区域。所以当拷贝的集合修改了集合对象内的数据,那么源集合对象也就随之改变了,这样的效果我们称之为Java集合对象的浅复制,即只是在栈中拷贝了,而堆中的数据并没有拷贝。而深度复制则是同时在栈中和堆中的数据进行拷贝,这样,其拷贝的集合和被拷贝的集合已经没有任何关系了。
2.一个例子
新建一个Demo类
- public class Demo {
- private int demoValue;
- public void setDemoValue(int value){
- this.demoValue = value;
- }
- public int getDemoValue(){
- return this.demoValue;
- }
- public Demo(){
- }
- public Demo(int demoValue){
- this.demoValue = demoValue;
- }
- }
接下来,我们试验一下浅复制:
- @Test
- public void testCommonCopy() {
- // Here I create a source collection.
- ArrayList<Demo> sourceCollection = new ArrayList<Demo>();
- // Here I add some objects to sourceCollection.
- sourceCollection.add(new Demo(1));
- sourceCollection.add(new Demo(2));
- // Here I create a new empty collection.
- ArrayList<Demo> newCollection = new ArrayList<Demo>();
- newCollection.addAll(sourceCollection);
- // Now I modify some objects in new collection.
- newCollection.get(0).setDemoValue(3);
- // Now We verify what it is inside the source collection.
- for(Demo demo : sourceCollection){
- System.out.println(demo.getDemoValue());
- }
- // Now I verify if the source Collection is modified.
- Assert.assertEquals(sourceCollection.get(0).getDemoValue(),1);
- }
对其的执行结果,很明显,newCollection中改变的Demo对象在SourceCollection中也跟着改变了,这说明两个集合中的Demo对象是同一个对象。这也是浅复制所存在的弊端。那么如何将两个集合独立开来呢,即如何进行深度复制,我们不烦继续往下阅读:
- protected Demo clone() throws CloneNotSupportedException {
- return (Demo)super.clone();
- }
然后我们来进行深度复制:
- @Test
- public void testCopyDeep() throws Exception{
- ArrayList<Demo> sourceCollection = new ArrayList<Demo>();
- sourceCollection.add(new Demo(1));
- sourceCollection.add(new Demo(2));
- ArrayList<Demo> newCollection = new ArrayList<Demo>();
- for(Demo demo : sourceCollection){
- newCollection.add(demo.clone());
- }
- newCollection.get(0).setDemoValue(3);
- for(Demo demo : sourceCollection){
- System.out.println(demo.getDemoValue());
- }
- Assert.assertEquals(sourceCollection.get(0).getDemoValue(),1);
- }
最后我们来观察一下结果:搞定
接下来我们来分析一下出现这个现象的原因:
原文博客:http://blog.csdn.net/qq_29329775/article/details/49516247
转载---Java集合对象的深度复制与普通复制的更多相关文章
- [转载] Java集合---HashMap源码剖析
转载自http://www.cnblogs.com/ITtangtang/p/3948406.html 一.HashMap概述 HashMap基于哈希表的 Map 接口的实现.此实现提供所有可选的映射 ...
- [转载] Java集合框架之小结
转载自http://jiangzhengjun.iteye.com/blog/553191 1.Java容器类库的简化图,下面是集合类库更加完备的图.包括抽象类和遗留构件(不包括Queue的实现): ...
- [转载]Java集合容器简介
Java集合容器主要有以下几类: 1,内置容器:数组 2,list容器:Vetor,Stack,ArrayList,LinkedList, CopyOnWriteArrayList(1.5),Attr ...
- java集合对象区别二
集合包是Java中最常用的包,它最常用的有Collection和Map两个接口的实现类,Collection用于存放多个单对象,Map用于存放Key-Value形式的键值对. Collection中常 ...
- Java集合容器的深度理解
Java容器里有很多写好的容器API,这使我们很方便的可以存储.操作我们的数据. 下面是我写的容器的特点,一些容器的不同之处,从底层源码解析一下容器实现原理 一.常用的容器目录 上图可以看出,java ...
- [转载]Java集合框架的常见面试题
http://www.jfox.info/40-ge-java-ji-he-lei-mian-shi-ti-he-da-an 整理自上面链接: Java集合框架为Java编程语言的基础,也是Java面 ...
- [转载]Java集合系列大全总结
Java 集合系列目录(Category) 22:06:49 2019-02-27
- java集合对象实现原理
1.集合包 集合包是java中最常用的包,它主要包括Collection和Map两类接口的实现. 对于Collection的实现类需要重点掌握以下几点: 1)Collection用什么数据结构实现? ...
- Java集合对象比对
1. 场景描述 通过java代码从外围接口中获取数据并落地,已经存在的不落地,不存在的落地,因有部分字段变化是正常的,只需比对3个字段相同即为相同. 2. 解决方案 设置定时任务(三个标签完成spri ...
随机推荐
- Web3D编程入门总结——WebGL与Three.js基础介绍
/*在这里对这段时间学习的3D编程知识做个总结,以备再次出发.计划分成“webgl与three.js基础介绍”.“面向对象的基础3D场景框架编写”.“模型导入与简单3D游戏编写”三个部分,其他零散知识 ...
- RCNN--对象检测的又一伟大跨越 2(包括SPPnet、Fast RCNN)(持续更新)
继续上次的学习笔记,在RCNN之后是Fast RCNN,但是在Fast RCNN之前,我们先来看一个叫做SPP-net的网络架构. 一,SPP(空间金字塔池化,Spatial Pyramid Pool ...
- Java中的4种代码块
一.普通代码块 直接在一个方法中出现的{}就称为普通代码块,例子程序如下: public class CodeDemo01{ public static void main(String[] args ...
- wex5 教程之 图文讲解 文件上传attachmentSimple(1)
视频教程地址:http://v.youku.com/v_show/id_XMTc4NDAyMTY4OA==.html 效果预览: 1 调用attchmentSimple组件,打开文件管理器,并选中,显 ...
- 31、springmvc(注解)
回顾什么是springmvc,它与spring有什么关系 springmvc属于spring框架的后续产品,用在基于MVC的表现层开发,类似于struts2框架 参见<<springmvc ...
- 优秀Python学习资源收集汇总(强烈推荐)
Python是一种面向对象.直译式计算机程序设计语言.它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用縮进来定义语句块.与Scheme.Ruby.Perl ...
- linux初始化配置---主机名、关闭防火墙、关闭selinux
一.修改主机名 1.零时修改 [root@localhost network-scripts]# hostname jw07 然后就可以看到我们的主机名被修改了
- hibernate的二级缓存
缓存(Cache): 计算机领域非常通用的概念.它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能.缓存中的数 ...
- ms sql 经典语句【珍藏】
数据库中字段中有不需要"[演示数据请勿真实购买]" 例如: update Hishop_Products set ProductName = replace(ProductName ...
- manacher浅析
manacher算法的输入是一个字符串,可以计算出以每个字符为中心的最长回文子串的半径.为了避免讨论奇数偶数,将原串的每两个字母之间以及前后各加一个特殊字母,比如'#',那么对于abcbb就变成了 # ...