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

mei*_*ryo 0 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]]
Run Code Online (Sandbox Code Playgroud)

上面的代码显示了2个列表.当我添加list2(包含foo)list1它们现在都包含foo.但是当我修改list2bar,list1也会改变.我一直认为add方法只给出了一份list2list1我做什么list2也不会改变对list1.

我如何才能加入list2,list1但允许list2在将来自由修改,以免list1再次受到影响?

Pet*_*rey 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]]
Run Code Online (Sandbox Code Playgroud)

要么

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

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

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);
}
Run Code Online (Sandbox Code Playgroud)

  • @nhahtdh使用特定于集合的方法通常不是一个好主意.这通常意味着你正在尝试做一些不寻常和怀疑的事情.BTW ArrayList.clone()返回一个`Object`,你必须使用未经检查的警告来强制转换它. (3认同)
  • @ nhahtdh ..另外一般不建议使用`clone()`方法.无论什么时候需要使用它,都要使用`copy constructor`,这是在这里完成的. (3认同)