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
。但是当我将list2
修改为bar
时,list1
也会发生变化。我一直认为add方法只提供list2
到list1
的副本,而我对list2
的操作不会更改为list1
。
我如何才能将list2
添加到list1
,但允许list2
以后可以自由修改,以便list1
不再受影响?
答案 0 :(得分: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);
}
答案 1 :(得分:1)
list1.add(list2.clone());
怎么样?
这将创建list2
的副本(分配内存,克隆内容等)并在list1
中引用它。
答案 2 :(得分:0)
您应克隆每个项目并添加到新列表。