2010-11-21 60 views
11

爲什麼我得到不同的行爲有:的Java中的addAll(集合)對新的ArrayList(集合)

  1. Collection col2 = new ArrayList(col);

  2. Collection col2 = new ArrayList();
    col2.addAll(col)

我的工作與觀衆,和代碼是複雜的,我試圖解釋問題的「根源」 。另一個有趣的事實是下一個...

//IF i use this code i have the correct behavior in my app: 
public void updateCollection(Collection<Object> col) { 
    this.objectCollection.clear(); 
    this.objectCollection.addAll(col); 
} 

//IF i use this code i have unexpected behavior in my app: 
public void updateCollection(Collection<Object> col) { 
    this.objectCollection=new ArrayList(col); 
} 
+7

請澄清一下,哪種確切的行爲令您感到困惑? – 2010-11-21 15:36:44

+0

我的代碼使用a)或b)有不同的行爲。在我看來,這兩次行動都會導致相同的結果,但顯然他們沒有。有些不同。 – marcolopes 2010-11-21 15:55:02

+2

你還是太模糊。怎麼了?不會發生什麼?請在您的環境中發佈[SSCCE](http://sscce.org)以及(未)預期結果。 – BalusC 2010-11-21 15:56:05

回答

14

此代碼:

public void updateCollection(Collection<Object> col) { 
    this.objectCollection.clear(); 
    this.objectCollection.addAll(col); 
} 

但這導致問題:

public void updateCollection(Collection<Object> col) { 
    this.objectCollection=new ArrayList(col); 
} 

我懷疑你的第一個方法,這種變化將引入了相同的問題:

public void updateCollection(Collection<Object> col) { 
    this.objectCollection = new ArrayList(); 
    this.objectCollection.clear(); 
    this.objectCollection.addAll(col); 
} 

爲什麼?顯然你有另一個引用objectCollection的地方。在代碼中的某處,另一個對象說(例如):

myCopyOfObjectCollection = theOtherObject.objectCollection;

如果你使用的是吸氣劑,那不會改變潛在的行爲 - 你仍然保留另一個參考。

因此,如果初始分配,比如,集合包含{1,2,3},你開始了:

  • this.objectCollection:{1,2,3}
  • 說。copyOfObjectCollection:{1,2,3}

當您將的ArrayList到this.objectCollection,並與比如說填充它,{4,5,6},你會得到這樣的:

  • this.objectCollection:{4,5,6}
  • that.copyOfObjectCollection:{1,2,3}

「即」 仍然指向原始的ArrayList。

5
Collection col2 = new ArrayList(col); 

將創建一個新ArrayList大小爲col.size()(+ 10%)和col所有元素複製到陣列。

Collection col2 = new ArrayList(); 

將創建一個初始大小爲10的新ArrayList(至少在Sun實現中)。

col2.addAll(col); 

將從col所有元素複製到col2ArrayList的端部,增大背襯陣列大小,如果需要的話。

所以,根據您的col集合大小,行爲會有所不同,但不會太多。

最好使用第一個選項 - 這將避免至少一個額外的後備陣列擴展操作。

+0

使用第一種方法我的代碼不起作用... – marcolopes 2010-11-21 15:53:34

0
public List getAdminImIdsWithValidShortNames(){ 
    return adminImIdsWithValidShortNames; 
} 

public void setAdminImIdsWithValidShortNames(List adminImIdsWithValidShortNames){ 
    this.adminImIdsWithValidShortNames=adminImIdsWithValidShortNames; 
} 

我覺得,容易是美麗的,只是發電機二傳手/吸氣方法是一個好習慣。 如果你第一次清除,那麼addAll,這個清單需要清除list的所有元素,然後addAll會額外支持數組的擴展操作,那不是科學。

剛更換時,這個變量會指向新的List,舊的列表會自動GC。