Arrays.asList(array) 和 new ArrayList<Integer>(Arrays.asList(array)) 之间的区别

2022-08-31 08:15:19

两者之间有什么区别

  • List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); // Copy

  • List<Integer> list2 = Arrays.asList(ia);

,其中整数数组在哪里?ia

我开始知道某些操作是不允许的。为什么会这样?它如何存储在内存中(引用/副本)?list2

当我随机排列列表时,不会影响原始数组,但会影响。但仍然有些令人困惑。list1list2list2

被上放到列表与创建新的列表有何不同?ArrayListArrayList

list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));

答案 1
  1. 首先,让我们看看这是做什么的:

    Arrays.asList(ia)
    

    它接受一个数组并创建一个实现的包装器,这使得原始数组可以作为列表使用。不复制任何内容,仅创建单个包装器对象。对列表包装器的操作将传播到原始数组。这意味着,如果对列表包装器进行随机排序,则原始数组也会被随机排列,如果覆盖元素,则会在原始数组中被覆盖,依此类推。当然,某些操作不允许在包装器上,例如在列表中添加或删除元素,您只能读取或覆盖元素。iaList<Integer>List

    请注意,列表包装器不会扩展 - 它是一种不同类型的对象。s有自己的内部数组,在其中存储其元素,并能够调整内部数组的大小等。包装器没有自己的内部数组,它只将操作传播到提供给它的数组。ArrayListArrayList

  2. 另一方面,如果您随后创建一个新数组

    new ArrayList<Integer>(Arrays.asList(ia))
    

    然后你创建新的 ,这是原始副本的完整,独立的副本。尽管在这里您也可以使用来创建包装器,但它仅在构建新包装器期间使用,之后会进行垃圾回收。这个新的结构完全独立于原始数组。它包含相同的元素(原始数组和此新数组在内存中引用相同的整数),但它会创建一个新的内部数组来保存引用。因此,当您随机播放,添加,删除元素等时,原始数组保持不变。ArrayListArrays.asListArrayListArrayListArrayList


答案 2

好吧,这是因为由 不是类型 。ArrayListArrays.asList()java.util.ArrayList

Arrays.asList()创建一个不扩展的类型,而只扩展 。ArrayListjava.util.Arrays$ArrayListjava.util.ArrayListjava.util.AbstractList