使用列表成员复制对象列表

时间:2014-03-05 08:02:24

标签: java object arraylist clone

如何复制包含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 个答案:

答案 0 :(得分: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());

    }

}