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

wel*_*lly 1 java memory reference

说我有以下代码,

LinkedList partials = new LinkedList();
partials.add(new ArrayList());
ArrayList head = partials.element();
head.add("Test");
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*eet 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());
Run Code Online (Sandbox Code Playgroud)

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

  • @Charlotte:这会改变我对你可能的能力水平的看法,并且不需要这个对话.如果您通常使用泛型,请在问题*或*中使用它们,至少在您通常使用它们的问题中进行解释.另外,在这种情况下,它确实*有所作为,因为对于`List <String>`我们会*知道*由于字符串的不变性,不需要深度复制. (2认同)