的ArrayList <数组列表>&GT;由正在添加的ArrayList备份

时间:2016-09-17 23:46:22

标签: java arraylist collections

我正在创建ArrayList ArrayList并向其添加ArrayLists。但每当我对ArrayList进行更改时,它都会反映在ArrayList<ArrayList>中。

示例:

List<List<String>> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<String>();
list2.add("Cat");
list1.add(list2);  //no problem
list2.clear();
list2.add("Dog");
list1.add(list2);  //problem! the cat is replaced by two dogs this time!!

如何确保list2中没有反映list1的更新?

2 个答案:

答案 0 :(得分:1)

我从以下等效但可运行的程序中观察到的内容:

import java.util.List;
import java.util.ArrayList;

public class Test1 {


    public static void main(String[] args){

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

        list2.add("Cat");
        System.out.println(list2);

        list1.add(list2); 
        System.out.println(list1);

        list2.clear();
        System.out.println(list2);

        list2.add("Dog");
        System.out.println(list2);

        list1.add(list2);
        System.out.println(list2);
        System.out.println(list1);

        if(list1.get(0) == list1.get(1)) {
            System.out.println("Lists at position 0 and 1 are the same");
        }

    }
}

它不是那个&#34;猫被两只狗替换了#34;正如你在代码的评论中写的那样,但最后,即在最后一个语句之后,list1包含两个列表,每个列表包含一个&#34; Dog&#34;。

这当然是因为当您第二次将list2添加到list1 时,您实际上并未添加 new 列表,但是同一个。您可能认为通过清除list2然后再添加它会添加一个包含新项目的新列表&#34; Dog&#34;,但您实际做的是修改同一个对象并添加相同的参考。请注意,list2list1参考

您需要做的是创建一个新的ArrayList对象,例如:

ArrayList<String> list3 = new ArrayList<String>();
list3.add("Dog");
list1.add(list3);

而不是清除list2并再次添加。

还查看这些文章:

  1. Why can't you have a "List<List<String>>" in Java?

  2. Working with a List of Lists in Java

  3. What are classes, references and objects?

答案 1 :(得分:1)

简短回答......替换

list2.clear();

list2 = new ArrayList<String>();

问题正在发生,因为list1.add(list2)list2的引用添加到list1。它不会在任何时候复制list2引用的列表。因此,您最终将对同一列表对象的多个引用添加到list1

这是Java参数传递的工作方式的结果,以及集合API全部设计的工作方式。