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

首先是对Java集合对象得浅复制与深度复制的理解 最近在开发中遇到了一些关于集合复制的一些问题,普通的集合复制只是将内存中栈的地址快拷贝一份,使得一个新的集合对象指向这个地址块,但是集合中的对象变量却是指向堆中的同一块区域。所以当拷贝的集合修改了集合对象内的数据,那么源集合对象也就随之改变了,这样的效果我们称之为Java集合对象的浅复制,即只是在栈中拷贝了,而堆中的数据并没有拷贝。而深度复制则是同时在栈中和堆中的数据进行拷贝,这样,其拷贝的集合和被拷贝的集合已经没有任何关系了。 接下来我们来看一个简单的例子

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;  
}  
}
复制代码

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

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对象是同一个对象。这也是浅复制所存在的弊端。那么如何将两个集合独立开来呢,即如何进行深度复制,我们不烦继续往下阅读:

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

@Override  
protected Demo clone() throws CloneNotSupportedException {             
return (Demo)super.clone();
复制代码

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

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);  
}  
复制代码

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

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

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

最后,给大家推荐一下Wiki上的关于对象复制的文章,en.wikipedia.org/wiki/Object…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值