0
ArrayList<ArrayList<String>> list1 = new ArrayList<ArrayList<String>>();
ArrayList<String> list2 = new ArrayList<String>();

list2.add("foo");
System.out.println(list2); //[foo]
list1.add(list2);
System.out.println(list1); //[[foo]]
list2.set(0, "bar");
System.out.println(list2); //[bar]
System.out.println(list1); //[[bar]]

上面的代码显示了 2 个列表。当我将list2(包含foo)添加到list1它们时,它们现在都包含foo. 但是当我修改list2bar,list1也会改变。我一直认为 add 方法只提供 to 的副本,list2list1我所做的 tolist2不会改变list1.

list2我怎样才能让它成为我添加list1但允许list2在未来自由修改所以list1不会再次受到影响?

4

3 回答 3

6

在 Java中,引用是按值传递的,而不是引用的对象。这意味着list2.add(list1);不能更改引用list1,但它需要对同一对象的引用,并且如果您更改它是可见的。

你应该写这个的方式是

List<List<String>> list1 = new ArrayList<List<String>>();
List<String> list2 = new ArrayList<String>();

list2.add("foo");
System.out.println(list2); //[foo]
list1.add(new ArrayList<String>(list2)); // take a copy of the list.
System.out.println(list1); //[[foo]]
list2.set(0, "bar");
System.out.println(list2); //[bar]
System.out.println(list1); //[[foo]]

或者

list1.add(list2); 
list2 = new ArrayList<String>();
list2.add("bar");
System.out.println(list2); //[bar]
System.out.println(list1); //[[foo]]

我上面的例子很简单,但我的实际问题隐藏在嵌套循环等中。

List<List<String>> list1 = new ArrayList<List<String>>();

for(some loop) {
    List<String> list2 = new ArrayList<String>();
    // populate list2, can be smaller than the previous list2 !!
    list1.add(list2);
}
于 2012-12-29T14:54:06.973 回答
1

怎么样list1.add(list2.clone());?这将创建list2(分配内存、克隆内容等)的副本并将对它的引用放入list1.

于 2012-12-29T14:54:44.087 回答
0

您应该克隆每个项目并添加到新列表中。

于 2012-12-29T14:55:22.497 回答