转载---Java集合对象的深度复制与普通复制

原博文:http://blog.csdn.net/qq_29329775/article/details/49516247

最近在做算法作业时出现了错误,原因是没有弄清楚java集合的深度复制和浅度复制的区别。

1.首先是对Java集合对象得浅复制与深度复制的理解

普通的集合复制只是将内存中栈的地址快拷贝一份,使得一个新的集合对象指向这个地址块,但是集合中的对象变量却是指向堆中的同一块区域。所以当拷贝的集合修改了集合对象内的数据,那么源集合对象也就随之改变了,这样的效果我们称之为Java集合对象的浅复制,即只是在栈中拷贝了,而堆中的数据并没有拷贝。而深度复制则是同时在栈中和堆中的数据进行拷贝,这样,其拷贝的集合和被拷贝的集合已经没有任何关系了。

2.一个例子

新建一个Demo类

 1 public class Demo {
 2
 3     private int  demoValue;
 4
 5     public void setDemoValue(int value){
 6         this.demoValue = value;
 7     }
 8
 9     public int getDemoValue(){
10         return this.demoValue;
11     }
12
13     public Demo(){
14
15     }
16
17     public Demo(int demoValue){
18         this.demoValue = demoValue;
19     }
20 }

接下来,我们试验一下浅复制:

 1     @Test
 2 public void testCommonCopy() {
 3
 4     // Here I create a source collection.
 5     ArrayList<Demo> sourceCollection = new ArrayList<Demo>();
 6
 7     // Here I add some objects to sourceCollection.
 8     sourceCollection.add(new Demo(1));
 9     sourceCollection.add(new Demo(2));
10
11     // Here I create a new empty collection.
12     ArrayList<Demo> newCollection = new ArrayList<Demo>();
13     newCollection.addAll(sourceCollection);
14
15     // Now I modify some objects in new collection.
16     newCollection.get(0).setDemoValue(3);
17
18     // Now We verify what it is inside the source collection.
19     for(Demo demo : sourceCollection){
20         System.out.println(demo.getDemoValue());
21     }
22
23     // Now I verify if the source Collection is modified.
24     Assert.assertEquals(sourceCollection.get(0).getDemoValue(),1);
25 }  

对其的执行结果,很明显,newCollection中改变的Demo对象在SourceCollection中也跟着改变了,这说明两个集合中的Demo对象是同一个对象。这也是浅复制所存在的弊端。那么如何将两个集合独立开来呢,即如何进行深度复制,我们不烦继续往下阅读:

首先我们先对Demo类作一下处理,使其实现Cloneable接口,并重写它的clone方法

1 protected Demo clone() throws CloneNotSupportedException {
2     return (Demo)super.clone();
3 }

然后我们来进行深度复制:

 1 @Test
 2 public void testCopyDeep() throws Exception{
 3     ArrayList<Demo> sourceCollection = new ArrayList<Demo>();
 4     sourceCollection.add(new Demo(1));
 5     sourceCollection.add(new Demo(2));
 6
 7     ArrayList<Demo> newCollection = new ArrayList<Demo>();
 8     for(Demo demo : sourceCollection){
 9         newCollection.add(demo.clone());
10     }
11     newCollection.get(0).setDemoValue(3);
12     for(Demo demo : sourceCollection){
13         System.out.println(demo.getDemoValue());
14     }
15     Assert.assertEquals(sourceCollection.get(0).getDemoValue(),1);
16 }  

最后我们来观察一下结果:搞定

接下来我们来分析一下出现这个现象的原因:

深度复制:如图:A中具有X1,X2,X3...Xn的数据,深度复制则对其每个堆和栈中的数据都进行一次拷贝,生成对应的Y1,Y2,Y3以及B对象。此时,A与B已经分别存放在不同的地址单元,所以A中改了数据,B中的数据不变,反之亦然。

浅复制:如图:A复制成B,但是A和B中的数据均指向同一个X1,X2,X3...Xn,所以当A通过某种方法改变了数据,对于B来说,其中的数据也改变了。

原文博客:http://blog.csdn.net/qq_29329775/article/details/49516247

时间: 2024-08-01 22:36:50

转载---Java集合对象的深度复制与普通复制的相关文章

[转载] Java集合---HashMap源码剖析

转载自http://www.cnblogs.com/ITtangtang/p/3948406.html 一.HashMap概述 HashMap基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同.)此类不保证映射的顺序,特别是它不保证该顺序恒久不变. 值得注意的是HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collection

java集合对象区别二

集合包是Java中最常用的包,它最常用的有Collection和Map两个接口的实现类,Collection用于存放多个单对象,Map用于存放Key-Value形式的键值对. Collection中常用的又分为两种类型的接口:List和Set,两者最明显的差别为List支持放入重复的对象,而Set不支持.List接口常用的实现类有:ArrayList,LinkedList,Vector和Stack:Set接口常用的实现有HashSet,TreeSet.而Map的常用实现有TreeMap和Hash

[转载] Java集合框架之小结

转载自http://jiangzhengjun.iteye.com/blog/553191 1.Java容器类库的简化图,下面是集合类库更加完备的图.包括抽象类和遗留构件(不包括Queue的实现): 2.ArrayList初始化时不可指定容量,如果以new ArrayList()方式创建时,初始容量为10个:如果以new ArrayList(Collection c)初始化时,容量为c.size()*1.1,即增加10%的容量:当向ArrayList中添加一个元素时,先进行容器的容量调整,如果容

[转载]Java集合框架的常见面试题

http://www.jfox.info/40-ge-java-ji-he-lei-mian-shi-ti-he-da-an 整理自上面链接: Java集合框架为Java编程语言的基础,也是Java面试中很重要的一个知识点.这里,我列出了一些关于Java集合的重要问题和答案. 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector.Stack.HashTable和Array.随着集合的广泛使用, Java1.2提出了囊括所有集

java集合对象区别一

Vector和ArrayList 1.vector是线程同步的,所以他也是线程安全的,而ArrayList是线程异步的,是不安全的.如果不考虑到线程的安全因素,一般用ArrayList效率较高. 2.如果集合中的元素的数目大于目前集合数组的长度时,Vector增长率为目前数组长度的100%,而ArrayList增长率为目前数组长度的50%.如果在集合中使用数据量比较大的数据,用vector有一定的优势. 3.如果查找一个制定位置的数据,vector和ArrayList使用的时间是相同的,都是0(

Java集合 Json集合之间的转换

1. Java集合转换成Json集合 关键类:JSONArray jsonArray = JSONArray.fromObject(Object obj); 使用说明:将Java集合对象直接传进JSONArray.fromObject()中,得到一个JSONArray集合,再直接使用JSONArray的toString()方法,便可得到json集合 示例代码: @Test public void testCreateJsonArray() { //Java集合 List<Employee> l

Java 集合(ArrayList)应用

JAVA集合 对象数组 集合类之ArrayList 学生管理系统 NO.one 对象数组 1.1 对象数组描述 A:基本类型的数组:存储的元素为基本类型 int[] arr={1,2,3,4} B:对象数组:存储的元素为引用类型 Student[] stus=new Student[3]; Student代表一个自定义类 Stus数组中stus[0],stus[1],stus[2]的元素数据类型为Student, 都可以指向一个Student对象 1.2 对象数组案例: 创建一个学生数组,存储三

转载-------- JSON 与 对象 、集合 之间的转换 JSON字符串和java对象的互转【json-lib】

转载--*--*---- 在开发过程中,经常需要和别的系统交换数据,数据交换的格式有XML.JSON等,JSON作为一个轻量级的数据格式比xml效率要高,XML需要很多的标签,这无疑占据了网络流量,JSON在这方面则做的很好,下面先看下JSON的格式, JSON可以有两种格式,一种是对象格式的,另一种是数组对象, {"name":"JSON","address":"北京市西城区","age":25}//JS

JAVA对象任意深度克隆clone工具类分享

原文:JAVA对象任意深度克隆clone工具类分享 源代码下载地址:http://www.zuidaima.com/share/1550463408114688.htm package com.zuidaima.n_app.util; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import jav