1. 程式人生 > >ArrayList深拷貝的一種實現方法

ArrayList深拷貝的一種實現方法

大家應該理解淺拷貝和深拷貝的區別:

淺拷貝:被複制物件的任何變數都含有和原來的物件相同的值,而任何的對其他物件的引用仍然指向原來的物件。對拷貝後的引用的修改,還能影響原來的物件。

深拷貝:把要複製的物件所引用的物件都複製了一遍,對現在物件的修改不會影響原有的物件。

如果大家還不理解,在網上看到一個人的比喻很有意思:

就好比一個爸爸一個兒子 
淺拷貝:你克隆一下,只得到一個爸爸,這是淺 
深拷貝:你克隆一下,既得到了爸爸,又得到了兒子,這是深 
另外,如果你克隆的物件裡面還包括其他物件,比如汽車物件裡還有座位物件,那麼淺的結果就是汽車被拷貝了,座位並沒有,深的話,就是一起都拷貝了。

下面,給大家說一下如何實現ArrayList的深拷貝的一種實現方式:

有一個類Userinfo,需要實現Serializable介面,可以序列化。

import java.io.Serializable;   
  
public class Userinfo implements Serializable    
{   
    private int id;   
    private String name;   
    public int getId() {   
        return id;   
    }   
    public void setId(int id) {   
        this.id = id;   
    }   
    public String getName() {   
        return name;   
    }   
    public void setName(String name) {   
        this.name = name;   
    }   
       
}  
下面是我的一個測試類:
package test;   
  
import java.io.ByteArrayInputStream;   
import java.io.ByteArrayOutputStream;   
import java.io.IOException;   
import java.io.ObjectInputStream;   
import java.io.ObjectOutputStream;   
import java.util.ArrayList;   
import java.util.List;   
  
public class TestMain {   
  
    /**  
     * @param args  
     */  
    public static void main(String[] args) {   
        // TODO Auto-generated method stub   
        List src = new ArrayList(2);   
        Userinfo ui1 = new Userinfo();   
        ui1.setId(1);   
        ui1.setName("aaa");   
        src.add(ui1);   
           
        Userinfo ui2 = new Userinfo();   
        ui1.setId(2);   
        ui1.setName("bbb");   
        src.add(ui2);   
           
        List dest = new ArrayList(2);   
           
        TestMain test = new TestMain();   
       
        try {   
            dest = test.deepCopy(src);   
        } catch (IOException e) {   
            // TODO Auto-generated catch block   
            e.printStackTrace();   
        } catch (ClassNotFoundException e) {   
            // TODO Auto-generated catch block   
            e.printStackTrace();   
        }   
       
           
        System.out.println(src==dest);   
        Userinfo u = (Userinfo)src.get(0);   
        Userinfo uu = (Userinfo)dest.get(0);   
        uu.setName("dkkdkddk");   
        System.out.println(u.getName());   
           
        System.out.println(uu.getName());   
       
    }   
  
    public List deepCopy(List src) throws IOException, ClassNotFoundException{   
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();   
        ObjectOutputStream out = new ObjectOutputStream(byteOut);   
        out.writeObject(src);   
       
        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());   
        ObjectInputStream in =new ObjectInputStream(byteIn);   
        List dest = (List)in.readObject();   
        return dest;   
    }   
}  


就是把ArrayList的原來的物件進行序列化,然後通過反序列化讀取出來,就可以了。

當然,記著放到集合中的元素也要能夠序列化,所以必須實現Serializable介面。

在此,也歡迎大家提出其它的ArrayList深拷貝實現方法。


//------------------------------------------------------------------------------------------------------------

List list1 = new ArrayList();
List list2 = new ArrayList(list1);
這種方式達不到深拷貝的。