在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)); 
  1. 首先,让我们看看这是什么:

     Arrays.asList(ia) 

    它接受一个数组ia并创build一个实现List<Integer>的包装器,它使得原始数组成为一个列表。 没有任何东西被复制,只有一个包装对象被创build。 列表包装上的操作被传播到原始数组。 这意味着如果你洗牌列表包装,原来的数组也被洗牌,如果你覆盖一个元素,它会被覆盖在原始数组等。当然,一些List操作不允许在包装,如添加或从列表中删除元素,则只能读取或覆盖元素。

    请注意列表包装不扩展ArrayList – 它是一种不同types的对象。 ArrayList有它们自己的内部数组,它们存储它们的元素,并能够调整内部数组的大小等等。包装器没有自己的内部数组,它只传递给它的数组。

  2. 另一方面,如果你随后创build一个新的数组

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

    那么你创build了一个新的ArrayList ,它是一个完整的独立副本。 虽然在这里也使用Arrays.asList创build包装器,但仅在构build新的ArrayList并在之后进行垃圾回收。 这个新的ArrayList的结构完全独立于原始数组。 它包含相同的元素(原始数组和这个新的ArrayList在内存中引用相同的整数),但它创build了一个新的内部数组,它包含引用。 所以当你洗牌,添加,删除元素等,原来的数组是不变的。

那么这是因为Arrays.asList()产生的ArrayList不是java.util.ArrayListtypes。 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()); } } }