實現(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");

這時,獲取source.get(0)的name值,也變成了“CDE”。
為了解決這個問題,使得改變copy中的值,不影響source中的數(shù)據(jù),則要進(jìn)行深拷貝。
即,對A類實現(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;
    }

    //實現(xiàn)這個方法
    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對對象和基本數(shù)據(jù)類型的處理是不一樣的。在Java中用對象作為入口參數(shù)的傳遞則缺省為“引用傳遞”,也就是說僅僅傳遞了對象的一個“引用”,這個引用的概念與C語言中的指針引用是一樣的。當(dāng)函數(shù)體內(nèi)部對這個變量進(jìn)行改變時,實質(zhì)上就是對這個對象進(jìn)行直接操作。
除此之外,在任何用“=”向?qū)ο笞兞抠x值的時候都是“引用傳遞”。

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

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

此處的A的成員變量String[],影子clone對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ù)雜的成員變量時,如Vector等存儲對象地址的容器時,就必須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也要實現(xiàn)相應(yīng)clone方法  
            }
        return a;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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

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