【问题标题】:Copy lists of objects with list members复制具有列表成员的对象列表
【发布时间】:2014-04-07 03:57:12
【问题描述】:

我如何复制包含 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());

【问题讨论】:

    标签: java object arraylist clone


    【解决方案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());
    
        }
    
    }
    

    【讨论】:

    • 好的,您的解决方案看起来不错,复制构造函数似乎是解决我的问题的好方法。但我认为您的示例中的以下行是不必要的: foobarsCopy.add(new Foobar(new ArrayList(Arrays.asList("d", "e", "f")), "foo"));
    • 不,没有必要。我添加它是为了修改 List 的副本,我认为这样会更清楚发生了什么......
    猜你喜欢
    • 2019-04-23
    • 1970-01-01
    • 2017-09-13
    • 2013-12-27
    • 2017-09-24
    • 2015-12-15
    • 2010-11-23
    • 1970-01-01
    • 2017-09-29
    相关资源
    最近更新 更多