使用java的list add方法传递值问题

时间:2012-12-29 14:51:33

标签: java arraylist pass-by-reference pass-by-value

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方法只提供list2list1的副本,而我对list2的操作不会更改为list1

我如何才能将list2添加到list1,但允许list2以后可以自由修改,以便list1不再受影响?

3 个答案:

答案 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)

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