关于ArrayList元素引用的简单Java问题

时间:2011-03-30 06:30:57

标签: java memory reference

说我有以下代码,

LinkedList partials = new LinkedList();
partials.add(new ArrayList());
ArrayList head = partials.element();
head.add("Test");

我希望“head”只是作为partials.element()结果的Arraylist的副本。但是,现在当我对“head”进行更改时,它会反映在Arraylist partials中。如何复制作为分段的第一个元素的Arraylist,以便对Arraylist进行更改不会反映在partials中?

2 个答案:

答案 0 :(得分:7)

有两种选择:

  • 调用带有另一个集合的ArrayList构造函数 - 即可复制
  • 致电clone()
  • 上的ArrayList

请注意,这两个副本都会创建副本 - 每个列表都包含对相同对象的引用。如果它们是不可变的(如字符串)那就没关系,但如果你想创建更深层的副本,你需要做更多的工作。

顺便说一下,你有没有理由不使用泛型?例如,我可能会使用:

LinkedList<ArrayList<String>> partials = new LinkedList<ArrayList<String>>();
ArrayList<String> list = new ArrayList<String>();
list.add("Test");

// Create a shallow copy and add a reference to that into the linked list
partials.add(new ArrayList<String>(list));

list.add("Another element");

// Prints 1, because the lists are distinct
System.out.println(partials.element().size());

如果没有任何内容可以更改链接列表中列表的内容,您可能需要查看Guava中可用的不可变集合,或使用Collections.unmodifiableList包装克隆。请注意,后者仅在原始列表中创建视图,因此您仍需要先执行克隆步骤。

答案 1 :(得分:1)

实际上代码无法在第3行编译:partials.element()返回一个Object(LinkedList的第一个元素),如果你想以这种方式使用它,你必须将它转换为ArrayList。

我同意您不需要泛型来使代码更容易添加。你也可以定义partials和head作为List而不是LinkedList&amp;数组列表。使用接口代替实现是一种很好的做法,避免在不需要时使用过多的特定方法,如element()。