在Arrays.asList(数组)与新的ArrayList <Integer>(Arrays.asList(ia))之间的区别
有什么区别
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy 2.List<Integer> list2 = Arrays.asList(ia);
ia
是整数数组。
我知道有些操作在list2
是不允许的。 为什么这样呢? 它如何存储在内存(引用/副本)?
当我洗牌的列表, list1
不会影响原来的数组,但list2
做。 但是list2
还是有些混乱。
如何将ArrayList
升级为列表与创build新的ArrayList
不同
list1 differs from (1) ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
-
首先,让我们看看这是什么:
Arrays.asList(ia)
它接受一个数组
ia
并创build一个实现List<Integer>
的包装器,它使得原始数组成为一个列表。 没有任何东西被复制,只有一个包装对象被创build。 列表包装上的操作被传播到原始数组。 这意味着如果你洗牌列表包装,原来的数组也被洗牌,如果你覆盖一个元素,它会被覆盖在原始数组等。当然,一些List
操作不允许在包装,如添加或从列表中删除元素,则只能读取或覆盖元素。请注意列表包装不扩展
ArrayList
– 它是一种不同types的对象。ArrayList
有它们自己的内部数组,它们存储它们的元素,并能够调整内部数组的大小等等。包装器没有自己的内部数组,它只传递给它的数组。 -
另一方面,如果你随后创build一个新的数组
new ArrayList<Integer>(Arrays.asList(ia))
那么你创build了一个新的
ArrayList
,它是一个完整的独立副本。 虽然在这里也使用Arrays.asList
创build包装器,但仅在构build新的ArrayList
并在之后进行垃圾回收。 这个新的ArrayList
的结构完全独立于原始数组。 它包含相同的元素(原始数组和这个新的ArrayList
在内存中引用相同的整数),但它创build了一个新的内部数组,它包含引用。 所以当你洗牌,添加,删除元素等,原来的数组是不变的。
那么这是因为Arrays.asList()
产生的ArrayList
不是java.util.ArrayList
types。 Arrays.asList()
创build一个types为java.util.Arrays$ArrayList
,它不扩展java.util.ArrayList
但只扩展java.util.AbstractList
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
在这种情况下, list1
的types是ArrayList
。
List<Integer> list2 = Arrays.asList(ia);
在这里,列表作为List
视图返回,这意味着它只有连接到该接口的方法。 因此为什么list2
不允许有一些方法。
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
在这里,你正在创build一个新的ArrayList
。 你只是在构造函数中传递一个值。 这不是一个铸造的例子。 在演员阵容中,看起来可能更像这样:
ArrayList list1 = (ArrayList)Arrays.asList(ia);
请注意,在Java 8中,上面的'ia'必须是Integer [],而不是int []。 一个int数组的Arrays.asList()返回一个单一元素的列表。 当使用OP的代码片段时,编译器会捕获这个问题,但是一些方法(例如Collections.shuffle())会默默无法做到你所期望的。
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy 2.List<Integer> list2 = Arrays.asList(ia);
在第2行中, Arrays.asList(ia)
返回一个在Arrays
定义的内部类对象的List
引用,它也被称为ArrayList
但是是私有的,只能扩展AbstractList
。 这意味着从Arrays.asList(ia)
返回的是与new ArrayList<Integer>
获得的不同的类对象。
您不能使用一些操作来第2行,因为Arrays
内的私人类不提供这些方法。
看看这个链接,看看你可以用私人内部类做什么: http : //grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ Arrays.java#Arrays.ArrayList
第1行创build了一个新的ArrayList
对象,从第2行获得元素。所以你可以做任何你想做的事情,因为java.util.ArrayList
提供了所有这些方法。
差异总结 –
当列表创build时不使用新的运算符Arrays.asList()方法,它返回包装的意思
1.您可以执行添加/更新操作。
2.在原始数组中完成的更改也会反映到List中,反之亦然。
package com.copy; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; public class CopyArray { public static void main(String[] args) { List<Integer> list1, list2 = null; Integer[] intarr = { 3, 4, 2, 1 }; list1 = new ArrayList<Integer>(Arrays.asList(intarr)); list1.add(30); list2 = Arrays.asList(intarr); // list2.add(40); Here, we can't modify the existing list,because it's a wrapper System.out.println("List1"); Iterator<Integer> itr1 = list1.iterator(); while (itr1.hasNext()) { System.out.println(itr1.next()); } System.out.println("List2"); Iterator<Integer> itr2 = list2.iterator(); while (itr2.hasNext()) { System.out.println(itr2.next()); } } }