两者的区别是什么?
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
2.List<Integer> list2 = Arrays.asList(ia);
其中ia
是整数阵列。
我知道在list2
中有些操作是不允许的。为什么会这样?
它是如何存储在内存中的(引用/复制)?
当我洗牌时,list1
不影响原始数组,但list2
会。但是list2
仍然有些令人困惑。
ArrayList
被上传到列表中与创建新的ArrayList
有什么不同?
list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
1.首先,让我们看看这有什么作用。
Arrays.asList(ia)
它接收一个数组`ia`并创建一个实现`List<Integer>`的包装器,使原来的数组可以作为一个列表。没有任何东西被复制,只有一个包装器对象被创建。对列表包装器的操作会传播到原始数组。这意味着如果你洗牌,原始数组也会被洗牌,如果你覆盖一个元素,它也会在原始数组中被覆盖,等等。当然,一些 "列表 "操作在封装器上是不允许的,比如从列表中添加或删除元素,你只能读取或覆盖元素。
请注意,列表包装器并没有扩展`ArrayList`,它是一种不同的对象。`ArrayList'有自己的内部数组,在其中存储元素,并且能够调整内部数组的大小等。包装器没有自己的内部数组,它只向给它的数组传播操作。
2.另一方面,如果你随后创建一个新的数组作为
new ArrayList<Integer>(Arrays.asList(ia))
那么你就创建了新的`ArrayList`,它是原始数组的一个完整的、独立的副本。尽管在这里你也使用`Arrays.asList`创建了包装器,但它只在构建新的`ArrayList`时使用,之后会被垃圾回收。这个新的`ArrayList`的结构是完全独立于原始数组的。它包含相同的元素(原始数组和这个新的`ArrayList`在内存中引用相同的整数),但是它创建了一个新的内部数组,用来保存引用。所以当你洗牌、添加、删除元素等时,原始数组是不变的。
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
在这种情况下,list1
属于ArrayList
类型。
List<Integer> list2 = Arrays.asList(ia);
在这里,列表被作为 "List "视图返回,意味着它只有附属于该接口的方法。因此,为什么有些方法在list2
上不被允许。
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
这里,你是在创建一个新的ArrayList
。你只是在构造函数中给它传递一个值。这不是一个铸造的例子。在铸造中,它可能看起来更像这样。
ArrayList list1 = (ArrayList)Arrays.asList(ia);