2012-07-24 69 views
1

編輯:有答案差異與最好的辦法Collection's分配,淺複製,懶惰複製和深層複製

我想有複製的集合不同方式的總體視圖更新的信息。我認爲我正在理解這個概念,但需要這麼做,我需要這樣一個總結(隨意修改我的文章)也是有用的。我有:

收藏a,b; //我忽略泛型

那麼,什麼是我的複製集合?:

  • 分配(完全相同的對象)

    a=b 
    
  • 淺拷貝(2點DIFF集合,同一個對象的機會因此如果我們從一個列表中添加/刪除一個對象,則不會在其他列表中反映出來)

    a = new ArrayList(b); // Or any other implementation of Collections 
    
    a = b.clone(); //This also? 
    
    b = new ArrayList(); //This also? 
    for (Object o : a) b.add(a); 
    
  • 懶惰複製(相同的java淺?)

  • 深複製(不同的名單與複製的對象,所以改變一個列表或對象不影響其他)

    b = new ArrayList(); // Or any other implementation of Collections 
    for (Object o : a) b.add(o.clone()); 
    

所以我想象一下這些情況:

收藏複製/複製(或返回DAO數據)

     SyncStateOfListing OriginalListingSafe OriginalObjectsStateSafe 
Mutual aware of changs 
********************** 
Assignment in other var   y - Mirrored   n      n 
Iterator*      y - Concurrnt.Exc n (remove())   n  

New is aware of old´ changes (RO ProxyView) 
****************************************** 

Coll.unmodifiableColl(orig)  y - Mirrored**  y NotSuppOpExc on RW n 
Coll.unmodif(orig).iterator()* y - Concurrnt.Exc y NotSuppOpExc on RW n 
Enum       y - ?    y No RW methods     

Independent copies 
****************** 
Shallow Copy     n     y      n 
Deep Copy      n     y      y (expensive) 


* Iterator we force to regenerate it in any use and we get Exceptions if at some moment the snapshot is obsolete, so we assure the state for which the operation is meant, transactionally. Cannot add elements or retraverse. 
** The "new" collection is totally mirrored for any change on the original, but internally, inner iterator is always used when traversing (the obvious stateful operation) so we get the same properties as when using it 

我的假設是否正確?

回答

2

作業: a和b將指向相同的列表,因此不會有任何副本。

淺和懶惰似乎相當於我。 對列表中的對象的引用將相同。你可以這樣說:「兩個列表中會出現相同的對象」。因此,修改一個列表的對象也會在第二個修改它,因爲這是同一個對象。

最後我想你應該寫這個深副本:

b = new ArrayList(); 
for (Object o : a) b.add(o.clone()); // and not a.clone() 

這種方式,你可以修改列表中的一個對象,而在B名單修改副本。

警告:使用可複製對象有一些限制。有關詳細信息,請參閱JDK文檔。