1

编辑:更新信息和答案

我试图对收集不同的复制方式有一个整体的看法。我想我得到了这个概念,但需要如此四舍五入,而且我需要这样的总结也很有用(随时修改我的帖子)。我有:

集合 a,b;//我省略了泛型

那么我复制收藏的机会有多大?:

  • 赋值(完全相同的对象)

    a=b
    
  • 浅拷贝(2 个不同的集合,相同的对象引用,所以如果我们从一个列表中添加/删除一个对象,则不会反映在另一个列表中)

    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

我的假设是否正确?

4

1 回答 1

2

分配: a 和 b 将指向同一个列表,因此那里不会有任何副本。

Shallow 和 Lazy 似乎与我等价。对列表中对象的引用将是相同的。您可能会这样说:“两个列表中将出现相同的对象”。因此,修改一个列表的对象也会在第二个列表中修改它,因为这是同一个对象。

最后我认为你应该为深拷贝写这个:

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

这样,您可以修改列表 a 中的一个对象,而无需修改列表 b 中的副本。

警告:使用可克隆对象有一些限制。有关详细信息,请参阅 JDK 文档。

于 2012-07-24T13:41:25.717 回答