为什么一个 ArrayList 上的 clear() 会清除另一个 ArrayList 中的元素?

Aks*_*mar 0 java collections arraylist

我想要的输出应该是:
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]

通过每次创建新的ArrayList对象

List<List<Integer>> result = new ArrayList<>();

    for(int i = 1; i <= 5; ++i){

      List<Integer> list = new ArrayList<>();

      for(int j = 1; j <= i; ++j){
        list.add(j);
      }
      result.add(list);
    }
    System.out.println(result);
Run Code Online (Sandbox Code Playgroud)

我得到所需的输出
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]

但是,在尝试使用时没有得到相同的结果clear()(以避免在每次迭代中创建新对象),并且在调用result Arraylist时也变得空clear()list Arraylist

List<Integer> list = new ArrayList<>();
List<List<Integer>> result = new ArrayList<>();

    for(int i = 1; i <= 5; ++i){
      for(int j = 1; j <= i; ++j){
        list.add(j);
      }
      result.add(list);
      list.clear();
    }
    System.out.println(result);
Run Code Online (Sandbox Code Playgroud)

我使用clear()得到以下输出
[[], [], [], [], []]-->不是我想要的输出

如何在不每次创建新对象(ArrayList 对象)并使用clear() 或任何其他概念的情况下实现所需的输出。

指向result and list ArrayList相同的引用,或者有其他原因导致错误的输出。请让我知道有关 ArrayList 主题的一些我不知道或缺乏的内容。

Bas*_*que 6

太长了;博士

\n

你说:

\n
\n

结果和列表ArrayList是否指向相同的引用

\n
\n

是的。

\n

要添加副本,请更改以下内容:

\n
result.add( list );\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x80\xa6 为:

\n
result.add( new ArrayList<>( list ) );\n
Run Code Online (Sandbox Code Playgroud)\n

细节

\n

您可能会认为这result.add(list);是添加的内容list。但不,该调用传递了您命名的对象的引用(指针,内存地址)。的内容与该调用无关。无论是空还是满,列表本身(即容器)就是您要传递给的内容。ArrayListlistlistadd

\n

因此,您将同一个列表添加五次。的所有元素都result指向同一个列表。如果添加到包含的列表中,所有五个元素都会result发生变化。如果清除添加的list,则所有五个元素都会result看到变化,所有五个元素都result指向同一个现在为空的列表。

\n

要添加不同的不可修改列表,请调用List.copyOf.

\n
result.add( List.copyOf( list ) );\n
Run Code Online (Sandbox Code Playgroud)\n

要添加不同的可修改列表,请构造新ArrayList对象。将现有列表传递给新列表的构造函数。

\n
result.add( new ArrayList<>( list ) );\n
Run Code Online (Sandbox Code Playgroud)\n

  • 我认为,通过“new ArrayList&lt;&gt;(list)”复制列表,然后从头开始重新填充“list”,其效率低于OP的第一个片段,它在每次迭代中创建并填充一个新列表。如果循环不使用“clear()”而只是在复制之前添加一个元素,情况会有所不同。但是,即使如此,也可以用[一种更有效的变体,根本不承担复制操作](/sf/answers/4843314801/)来代替。 (2认同)