實(shí)現(xiàn)list的深拷貝

本文引自:http://blog.sina.com.cn/s/blog_605f78830102uy6x.html
1.先來看一段代碼:
List<A> source = new ArrayList<A>();   
List<A> copy = new  ArrayList<A>();
A a = new A();        
a.setName("ABC“);
source.add(a);
copy.addAll(source);     //通過addAll()方法拷貝
copy.get(0).setName("CDE");

這時(shí),獲取source.get(0)的name值,也變成了“CDE”。
為了解決這個(gè)問題,使得改變copy中的值,不影響source中的數(shù)據(jù),則要進(jìn)行深拷貝。
即,對(duì)A類實(shí)現(xiàn)clone()方法:

public class A implements Cloneable{
    private String name;
    
    public A(){
    }

    public void setName(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    //實(shí)現(xiàn)這個(gè)方法
    protected A clone() throws CloneNotSupportedException {
        return (A)super.clone();
    }
}

然后,

for(int i = 0; i < source.size();i++){
    copy.add(source.get(i).clone());   
}

就可以進(jìn)行深拷貝了。

在此,再多描述一下關(guān)于Clone的內(nèi)容。
Java對(duì)對(duì)象和基本數(shù)據(jù)類型的處理是不一樣的。在Java中用對(duì)象作為入口參數(shù)的傳遞則缺省為“引用傳遞”,也就是說僅僅傳遞了對(duì)象的一個(gè)“引用”,這個(gè)引用的概念與C語(yǔ)言中的指針引用是一樣的。當(dāng)函數(shù)體內(nèi)部對(duì)這個(gè)變量進(jìn)行改變時(shí),實(shí)質(zhì)上就是對(duì)這個(gè)對(duì)象進(jìn)行直接操作。
除此之外,在任何用“=”向?qū)ο笞兞抠x值的時(shí)候都是“引用傳遞”。

一、當(dāng)Class A的成員變量類型是基本數(shù)據(jù)類型(外加String類型)時(shí),只要實(shí)現(xiàn)如上簡(jiǎn)單的clone(稱影子clone)就可以。但是如果Class A的成員變量是數(shù)組或者更復(fù)雜類型時(shí),就必須實(shí)現(xiàn)深度clone。

public class A implements Cloneable{
    private String[] name;
    
    public A(){
        name = new String[2];
    }

    public void setName(String[] name){
        this.name = name;
    }

    public String[] getName(){
        return name;
    }

    //實(shí)現(xiàn)這個(gè)方法
    protected A clone() throws CloneNotSupportedException {
        return (A)super.clone();
    }
}

此處的A的成員變量String[],影子clone對(duì)name數(shù)組clone他們的地址,需進(jìn)行深拷貝。

    protected A clone() throws CloneNotSupportedException {
            A a = (A)super.clone();
            a.name = (String[])name.clone();
        return a;
    }

二、需要注意的是,Class A存在更為復(fù)雜的成員變量時(shí),如Vector等存儲(chǔ)對(duì)象地址的容器時(shí),就必須clone徹底。

public class A implements Cloneable{
    private String[] name;
    private Vector<B> claB;
    
    public A(){
        name = new String[2];
        claB = new Vector<B>();
    }

    public void setName(String[] name){
        this.name = name;
    }

    public String[] getName(){
        return name;
    }

    public void setClaB(Vector<B> claB){
        this.claB = claB;
    }

    public Vector<B> getClaB(){
        return claB;
    }

    protected A clone() throws CloneNotSupportedException {
            A a = (A)super.clone();
            a.name = (String[])name.clone();
            a.claB = new Vector<B>();
            for(int i = 0;i < claB.size();i++){
                a.claB.add((B)claB.get(i).clone());//當(dāng)然Class B也要實(shí)現(xiàn)相應(yīng)clone方法  
            }
        return a;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 2018年5月4日 星期五 晴 因?yàn)榻裉炱谥锌荚?,七點(diǎn)半到校,史皓誠(chéng)早早的就起床了,洗刷完畢,給他下...
    史皓誠(chéng)媽媽閱讀 169評(píng)論 0 0
  • 如果我病了,我就不用考試了 太陽(yáng)落山之后,皮卡車在曠野里行駛,給人一種絕望的感覺。 讀研的時(shí)候我曾經(jīng)想先工作兩年,...
    路建華閱讀 154評(píng)論 1 0
  • 在 Python 的圈子里,關(guān)于 Python 2 和 Python 3 的爭(zhēng)論持續(xù)不斷,總是一波未平一波...
    Ulrich蚊子閱讀 1,242評(píng)論 3 3
  • 思睿教育·小荷作文第二十二期領(lǐng)袖成長(zhǎng)營(yíng)開營(yíng)啦!對(duì)于孩子們來說每一次成長(zhǎng)之旅都有不一樣的風(fēng)景,不同的體驗(yàn)。 思睿教育...
    思睿教育小荷作文閱讀 555評(píng)論 0 1
  • 1. 若突發(fā)意外導(dǎo)致腦死亡,我的器官如對(duì)他人有用,則捐出,其余器官捐給醫(yī)院。若自然死亡,則遺體捐獻(xiàn)給需要的醫(yī)院。 ...
    梁絳閱讀 1,125評(píng)論 3 1

友情鏈接更多精彩內(nèi)容