2014-03-05 65 views
1

如何複製包含ArrayList成員的對象的ArrayList。也有可能,列表中的對象的成員還包含ArrayList成員,等等。那麼是否有一種通用的方法來複制對象列表,無論其成員是什麼?使用列表成員複製對象列表

對所有涉及的對象實施Clone Interface似乎是一個壞主意,因爲I read that its broken

我創建了一個小SSCCE來舉例說明我的問題:

class Foobar { 
    public List<String> listMember; 
    public String  primitiveMember; 

    public Foobar() { 
     listMember = new ArrayList<String>(Arrays.asList("a", "b", "c")); 
     primitiveMember = "testABC"; 
    } 
} 
// Create list of Foobar 
List<Foobar> foobars = new ArrayList<Foobar>(); 
foobars.add(new Foobar()); 
// Copy list of Foobar 
List<Foobar> foobarsCopy = new ArrayList<Foobar>(); 
foobarsCopy.add(null); 
Collections.copy(foobarsCopy, foobars); 
// Modify source list 
foobars.get(0).listMember.add("-1-"); 
// Output of references 
System.out.println("Sourcelist has size of: " + foobars.get(0).listMember.size()); 
System.out.println("Destinationlist has size of: " + foobarsCopy.get(0).listMember.size()); 
System.out.println("Function 'Collections.copy(...) does not copy list members of members?: " + (foobars.get(0).listMember.size() == foobarsCopy.get(0).listMember.size()) + " - References: " + foobars.get(0).listMember.hashCode() + " vs " + foobarsCopy.get(0).listMember.hashCode()); 

回答

1

您可以使用一個拷貝構造函數,如果你不想使用可複製的接口。通過這種方式,您可以爲List元素的每個實例獲取新對象,併爲複製的List創建一個獨立的引用。總之,您將擁有Foobar元素的深層副本。

class Foobar { 
    public List<String> listMember; 
    public String  primitiveMember; 

    public Foobar() { 
     listMember = new ArrayList<String>(Arrays.asList("a", "b", "c")); 
     primitiveMember = "testABC"; 
    } 

    public Foobar(List<String> list, String primitive) { 
     this.listMember = list; 
     this.primitiveMember = primitive; 
    } 

    // Use a copy constructor instead of the Cloneable interface 
    public Foobar(Foobar foobar) { 
     this.primitiveMember = foobar.primitiveMember; 
     this.listMember = new ArrayList<String>(foobar.listMember); 
    } 

    public static void main(String[] args) { 
     // Create list of Foobar 
     List<Foobar> foobars = new ArrayList<Foobar>(); 
     foobars.add(new Foobar()); 

     // Copy list of Foobar with the copy constructor 
     List<Foobar> foobarsCopy = new ArrayList<Foobar>(foobars.size()); 
     for (Foobar f : foobars) { 
      foobarsCopy.add(new Foobar(f)); 
     } 

     // add a new Foobar instance (hashcode will be different now) 
     foobarsCopy.add(new Foobar(new ArrayList<String>(Arrays.asList("d", "e", "f")), "foo")); 

     // Modify source list (hashcode again will be different) 
     foobars.get(0).listMember.add("-1-"); 

     // Output of references 
     System.out.println("Sourcelist has size of: " + foobars.get(0).listMember.size()); 
     System.out.println("Destinationlist has size of: " + foobarsCopy.get(0).listMember.size()); 
     System.out.println("Function 'Collections.copy(...) does not copy list members of members?: " 
       + (foobars.get(0).listMember.size() == foobarsCopy.get(0).listMember.size()) 
       + "\n - References: " + foobars.get(0).listMember.hashCode() 
       + " vs " + foobarsCopy.get(0).listMember.hashCode()); 

    } 

} 
+0

oK,您的解決方案看起來不錯,複製構造函數似乎是解決我的問題的好方法。但我認爲您的示例中的以下行不是必需的:foobarsCopy.add(new Foobar(new ArrayList (Arrays.asList(「d」,「e」,「f」)),「foo」)); – alex

+0

不,這不是必需的。我添加它來修改列表的副本,我認爲這樣會更清楚發生了什麼... ... –