ArrayList深拷貝的一種實現方法
阿新 • • 發佈:2019-02-13
大家應該理解淺拷貝和深拷貝的區別:
淺拷貝:被複制物件的任何變數都含有和原來的物件相同的值,而任何的對其他物件的引用仍然指向原來的物件。對拷貝後的引用的修改,還能影響原來的物件。
深拷貝:把要複製的物件所引用的物件都複製了一遍,對現在物件的修改不會影響原有的物件。
如果大家還不理解,在網上看到一個人的比喻很有意思:
就好比一個爸爸一個兒子
淺拷貝:你克隆一下,只得到一個爸爸,這是淺
深拷貝:你克隆一下,既得到了爸爸,又得到了兒子,這是深
另外,如果你克隆的物件裡面還包括其他物件,比如汽車物件裡還有座位物件,那麼淺的結果就是汽車被拷貝了,座位並沒有,深的話,就是一起都拷貝了。
下面,給大家說一下如何實現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);
這種方式達不到深拷貝的。