Sealyu

          --- 博客已遷移至: http://www.sealyu.com/blog

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            618 隨筆 :: 87 文章 :: 225 評論 :: 0 Trackbacks
          <2016年8月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          常用鏈接

          留言簿(14)

          隨筆分類

          隨筆檔案

          友情鏈接

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          今天發(fā)現(xiàn)單獨的將一個ArrayList的對象添加到另外一個ArrayList的時候,總是源列表和目的列表相同的內(nèi)存地址。原因如下:

          偶然看到了Collections的copy(List desc,List src)方法.當(dāng)時就想這個方法和初始化一個List desc=new ArrayList(List c)【參數(shù)必須實現(xiàn)Collection接口】的區(qū)別。

          兩者的差別很大,后者是一個淺拷貝,只是對源list的元素進(jìn)行拷貝,拷貝的只是引用??截惡髢蓚€list的元素(引用)不同,但是引用所指向的對象是一樣的。即是兩個list的每個元素指向的還是通一內(nèi)存。然而前者是深拷貝,不光拷貝的是src的元素(引用),src內(nèi)每個元素的所指向的對象都進(jìn)行一次拷貝。即是兩個list的每個元素所指向的不是同一內(nèi)存。

          所以使用了Collections.copy()方法來進(jìn)行拷貝,但是這樣就接觸到了此方法所報出的異常:

          使用后者進(jìn)行拷貝的結(jié)果是:當(dāng)你的desc鏈表發(fā)生改變時,src也將會隨之改變。
          使用前者進(jìn)行拷貝時你又必須要注意目標(biāo)鏈表的長度必須要比源鏈表的長度大或者相等。

          舉例如下:
          List src1
          =new ArrayList(3)
          src1.add(
          "a");
          src2.add(
          "b");
          src3.add(
          "c");

          如果你使用下面方法copy鏈表
          /*******************************/
          List des1
          =new ArrayList(3);
          Collections.copy(des1,src1);
          /*******************************/
          將會出錯,拋出數(shù)組越界異常。
          當(dāng)時我怎么想都想不明白為什么,明明已經(jīng)設(shè)置了長度為3,為什么還會出錯!
          后來打印出des1.size()才知道des1的長度為0;3表示的是這個List的容納能力為3,并不是說des1中就有了3個元素。查看api才知道,它的capacity(容納能力大小)可以指定(最好指定)。而初始化時size的大小永遠(yuǎn)默認(rèn)為0,只有在進(jìn)行add和remove等相關(guān)操作時,size的大小才變化。然而進(jìn)行copy()時候,首先做的是將desc1的size和src1的size大小進(jìn)行比較,只有當(dāng)desc1的size 大于或者等于src1的size時才進(jìn)行拷貝,否則拋出IndexOutOfBoundsException異常。

          所以可以通過下面的方法指定目標(biāo)desc的大小
          /*******************************/
          List des1
          =new ArrayList(Array.asList(new object[src1.size]));//注意:new ArrayList(Collection col)參數(shù)必須要實現(xiàn)Collection 接口。
          Collections.copy(des1,src1);
          /*******************************/
          執(zhí)行第一句后size的大小是3,其實它是對一個空數(shù)組的淺拷貝。

          使用這位仁兄的方法,我這邊一直報錯說找不到此構(gòu)造函數(shù),估計是因為我使用了jdk6的原因,后來使用了替代方法,用apache的CollectionUtils:

          dest1 = new ArrayList();
          CollectionUtils.addAll(dest1, 
          new Object[src1.size()]);
          Collections.copy(dest1, src1);


          posted on 2009-10-27 16:24 seal 閱讀(10122) 評論(4)  編輯  收藏 所屬分類: Java基礎(chǔ)

          評論

          # re: 慎用java.util.Collections.copy()方法 2010-05-14 14:06 Mavk
          謝謝分享  回復(fù)  更多評論
            

          # re: 慎用java.util.Collections.copy()方法 2010-09-29 14:01 shigangxing
          Collections.copy(dest, src);也是淺拷貝,真正的深拷貝需要使用clone()實現(xiàn)。

          博主可以再確認(rèn)一下。  回復(fù)  更多評論
            

          # re: 慎用java.util.Collections.copy()方法 2011-08-03 15:28 金環(huán)三結(jié)
          2樓說的對,Collections.copy(dest, src);也是淺拷貝  回復(fù)  更多評論
            

          # re: 慎用java.util.Collections.copy()方法[未登錄] 2016-08-11 23:39 yf
          樓主誤認(rèn)。。二樓正解
          是Arrays.asList()....不是Array.asList()  回復(fù)  更多評論
            

          主站蜘蛛池模板: 江油市| 湖南省| 浪卡子县| 泸溪县| 遵化市| 岐山县| 斗六市| 鄂托克前旗| 天祝| 梅河口市| 克什克腾旗| 中山市| 孝昌县| 浦北县| 泌阳县| 明光市| 维西| 高雄县| 自贡市| 台前县| 嘉祥县| 鄂温| 阆中市| 石林| 哈尔滨市| 滨海县| 乌什县| 安远县| 曲靖市| 苏尼特左旗| 福海县| 福安市| 奉节县| 景谷| 高碑店市| 驻马店市| 施秉县| 织金县| 贺兰县| 和硕县| 镇巴县|