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

有什么区别

1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));  //copy
2.List<Integer> list2 = Arrays.asList(ia);

其中ArrayList是整数数组。

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

当我洗牌时,ArrayList不会影响原始阵列,但ArrayList会影响原始阵列。 但仍然有点混乱list2

ArrayList如何上传列表与创建新的ArrayList不同

list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
Dineshkumar asked 2019-08-13T09:38:13Z
13个解决方案
184 votes
  1. 首先,让我们看看它的作用:

    ArrayList

    它需要一个数组ArrayList并创建一个实现Arrays.asList的包装器,它使原始数组可用作列表。 没有复制任何内容,只创建了一个包装器对象。 列表包装器上的操作将传播到原始数组。 这意味着如果你改组列表包装器,原始数组也会被洗牌,如果你覆盖一个元素,它会在原始数组中被覆盖,等等。当然,包装器上不允许进行一些ArrayList操作, 比如从列表中添加或删除元素,您只能读取或覆盖元素。

    请注意,列表包装器不会扩展ArrayList - 它是一种不同类型的对象。 Arrays.asLists有自己的内部数组,它们存储它们的元素,并且能够调整内部数组的大小等。包装器没有自己的内部数组,它只将操作传播给给定的数组。

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

    ArrayList

    然后你创建新的ArrayList,这是原始的一个完整,独立的副本。 虽然在这里您也使用Arrays.asList创建包装器,但它仅在构建新的ArrayList时使用,之后进行垃圾收集。 这个新的ArrayList的结构完全独立于原始阵列。 它包含相同的元素(原始数组和新的ArrayList在内存中引用相同的整数),但它创建了一个新的内部数组,用于保存引用。 因此,当您对其进行随机播放,添加,删除元素等时,原始数组将保持不变。

Petr Pudlák answered 2019-08-13T09:39:10Z
19 votes

这是因为ArrayListArrays.asList()产生,不是java.util.ArrayList的类型。 Arrays.asList()创建一个ArrayList类型为java.util.Arrays$ArrayList但未扩展java.util.ArrayList但仅扩展java.util.AbstractList

Chris answered 2019-08-13T09:39:38Z
8 votes
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));  //copy

在这种情况下,list1的型号为ArrayList

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

这里,列表以ArrayList视图的形式返回,这意味着它只有附加到该接口的方法。 因此,为什么在list2上不允许某些方法。

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

在这里,您正在创建一个新的ArrayList.您只需在构造函数中传递一个值。 这不是铸造的例子。 在投射中,它可能看起来更像这样:

ArrayList list1 = (ArrayList)Arrays.asList(ia);
christopher answered 2019-08-13T09:40:22Z
3 votes

我在这里已经很晚了,无论如何感觉到文档参考的解释对于寻找答案的人来说会更好。

  1. java.util.Arrays中
  • 这是一个实用程序类,带有一堆静态方法来对给定的数组进行操作
  • asList是一个这样的静态方法,它接受输入数组并返回java.util.Arrays.ArrayList的对象,该对象是一个静态嵌套类,它扩展了AbstractList,它实现了List接口。
  • 所以Arrays.asList(inarray)在输入数组周围返回一个List包装器,但是这个包装器是java.util.Arrays.ArrayList而不是java.util.ArrayList,它引用相同的数组,因此向List包装数组添加更多元素会影响 也是一个也是我们不能改变长度的。
  1. 的java.util.ArrayList
  • ArrayList有一堆重载的构造函数

    public ArrayList() - //返回默认容量为10的arraylist

    public ArrayList(Collection c)

    public ArrayList(int initialCapacity)

  • 因此,当我们将Arrays.asList返回的对象,即List(AbstractList)传递给上面的第二个构造函数时,它将创建一个新的动态数组(这个数组大小增加,因为我们添加的元素多于其容量,新元素也不会影响orignal数组 浅层复制原始数组(浅层复制意味着它仅复制引用,并且不会创建与orignal数组中相同的新对象集)

Gautam Tadigoppula answered 2019-08-13T09:42:03Z
3 votes
String names[] = new String[]{"Avinash","Amol","John","Peter"};
java.util.List<String> namesList = Arrays.asList(names);

要么

String names[] = new String[]{"Avinash","Amol","John","Peter"};
java.util.List<String> temp = Arrays.asList(names);         

Above Statement在输入数组上添加了包装器。 所以像add&amp; amp; 删除将不适用于列表引用对象&#39; namesList&#39;。

如果您尝试在现有数组/列表中添加一个元素,那么您将获得&#34;线程中的异常&#34; main&#34;java.lang.UnsupportedOperationException&#34;.

以上操作是只读或查看的。
我们无法在列表对象中执行添加或删除操作。但

String names[] = new String[]{"Avinash","Amol","John","Peter"};
java.util.ArrayList<String> list1 = new ArrayList<>(Arrays.asList(names));

要么

String names[] = new String[]{"Avinash","Amol","John","Peter"};
java.util.List<String> listObject = Arrays.asList(names);
java.util.ArrayList<String> list1 = new ArrayList<>(listObject);

在上面的语句中,您创建了一个ArrayList类的具体实例,并将列表作为参数传递。

在这种情况下,方法添加&amp; remove将正常工作,因为两个方法都来自ArrayList类,所以在这里我们不会得到任何UnSupportedOperationException。
在Arraylist对象中进行的更改(方法在arraylist中添加或删除元素)将不会反映到原始java.util.List对象中。

String names[] = new String[] {
    "Avinash",
    "Amol",
    "John",
    "Peter"
};

java.util.List < String > listObject = Arrays.asList(names);
java.util.ArrayList < String > list1 = new ArrayList < > (listObject);
for (String string: list1) {
    System.out.print("   " + string);
}
list1.add("Alex"); //Added without any exception
list1.remove("Avinash"); //Added without any exception will not make any changes in original list in this case temp object.


for (String string: list1) {
    System.out.print("   " + string);
}
String existingNames[] = new String[] {
    "Avinash",
    "Amol",
    "John",
    "Peter"
};
java.util.List < String > namesList = Arrays.asList(names);
namesList.add("Bob"); // UnsupportedOperationException occur
namesList.remove("Avinash"); //UnsupportedOperationException
Avinash Pande answered 2019-08-13T09:43:19Z
2 votes

请注意,在Java 8中,&#39; ia&#39; 上面必须是Integer []而不是int []。 int数组的Arrays.asList()返回一个包含单个元素的列表。 使用OP的代码片段时,编译器将捕获该问题,但某些方法(例如Collections.shuffle())将无法按预期执行操作。

Carl Burke answered 2019-08-13T09:43:49Z
2 votes

首先,Arrays类是一个包含no的实用程序类。 对数组进行操作的实用程序方法(多亏了Arrays类,否则我们需要创建自己的方法来处理Array对象)

asList()方法:

  1. Arraylist方法是ArrayList类的实用方法之一,它是静态方法,这就是为什么我们可以通过它的类名调用这个方法(如Array
  2. 现在这里是扭曲,请注意,此方法不会创建新的Arraylist对象,它只返回对现有ArrayList对象的List引用(所以现在使用Array方法后,将创建对现有ArrayList对象的两个引用)
  3. 这就是原因,对Arraylist对象进行操作的所有方法都可能无法使用ArrayList这样的Array对象工作例如,Arrays大小的长度是固定的,因此你显然无法使用这个Array引用添加或删除ArrayList对象中的元素(如list.add(10)list.remove(10);否则会抛出UnsupportedOperationException)
  4. 您使用列表引用所做的任何更改都将反映在现有的Arraylists对象中(因为您使用列表引用操作现有的Array对象)

在第一种情况下,您正在创建一个新的Arraylist对象(在第二种情况下仅创建现有Array对象的引用但不是新的ArrayList对象),所以现在有两个不同的对象,一个是Array对象,另一个是ArrayList对象,之间没有连接 它们(因此在一个对象中的更改不会在另一个对象中反映/受影响(在2 ArrayArraylist是两个不同的对象的情况下)

情况1:

Integer [] ia = {1,2,3,4};
System.out.println("Array : "+Arrays.toString(ia));
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));  // new ArrayList object is created , no connection between existing Array Object
list1.add(5);
list1.add(6);
list1.remove(0);
list1.remove(0);
System.out.println("list1 : "+list1);
System.out.println("Array : "+Arrays.toString(ia));

案例2:

Integer [] ia = {1,2,3,4};
System.out.println("Array : "+Arrays.toString(ia));
List<Integer> list2 = Arrays.asList(ia); // creates only a (new ) List reference to existing Array object (and NOT a new ArrayList Object)
//  list2.add(5); //  it will throw java.lang.UnsupportedOperationException - invalid operation (as Array size is fixed)
list2.set(0,10);  // making changes in existing Array object using List reference - valid 
list2.set(1,11); 
ia[2]=12;     // making changes in existing Array object using Array reference - valid
System.out.println("list2 : "+list2);
System.out.println("Array : "+Arrays.toString(ia));
qaautodev answered 2019-08-13T09:45:09Z
1 votes
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());
        }
    }
}
VicXj answered 2019-08-13T09:45:33Z
1 votes

ArrayList(Arrays.asList());

此方法返回其自己的List实现。它将数组作为参数并在其上构建方法和属性,因为它不是从数组复制任何数据但使用原始数组,这会导致修改原始数组时 ArrayList(Arrays.asList());方法返回的列表。

另一方面。
ArrayList(Arrays.asList());是一个ArrayList类的构造函数,它以列表作为参数并返回一个独立于列表的ArrayList即。 在这种情况下,Arrays.asList()作为参数传递。这就是你看到这些结果的原因;

Kunal Singh Gusain answered 2019-08-13T09:46:26Z
1 votes

许多人已经回答了机械细节,但值得注意的是:这是Java的糟糕设计选择。

Java的interface ImmutableList方法记录为&#34;返回固定大小的列表...&#34;。 如果您获取其结果并调用(比方说)UnsupportedOperationException方法,则会抛出UnsupportedOperationException。这是不直观的行为! 如果一个方法说它返回List,那么标准的期望是它返回一个支持接口List方法的对象。开发人员不应该记住哪些方法创建了List这些方法。 实际上支持所有List方法。

如果他们将方法命名为interface ImmutableList,那就有意义了。 或者,如果他们只是让方法返回一个实际的UnsupportedOperationException(并复制支持数组),这将是有道理的。 他们决定赞成运行时性能和短名称,但却违反了最低惊喜原则和良好的O.O. 避免UnsupportedOperationExceptions的做法。

(此外,设计师可能已经制作了interface ImmutableList,以避免过多的UnsupportedOperationException。)

not-just-yeti answered 2019-08-13T09:47:25Z
0 votes
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));  //copy
2.List<Integer> list2 = Arrays.asList(ia);

在第2行,ArrayList返回java.util.ArrayList内部类对象的引用,该引用在Arrays中定义,也称为ArrayList,但是是私有的,仅扩展AbstractList.这意味着从Arrays.asList(ia)返回的是与new ArrayList<Integer>不同的类对象。

您不能对第2行使用某些操作,因为ArrayList中的内部私有类不提供这些方法。

看看这个链接,看看你可以用私有内部类做什么:[http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Arrays.java#Arrays.ArrayList]

第1行创建了一个新的ArrayList对象复制元素,从你从第2行获得的元素。所以你可以做任何你想做的事情,因为java.util.ArrayList提供了所有这些方法。

zek_w answered 2019-08-13T09:48:22Z
0 votes

差异摘要 -

当不使用新的运算符Arrays.asList()方法创建列表时,它返回Wrapper,这意味着

1.您可以执行添加/更新操作。

2.原始数组中完成的更改也将反映到List中     反之亦然。

Raj answered 2019-08-13T09:49:20Z
0 votes

回应一些评论,询问自Java 8以来Arrays.asList()的行为问题:

    int[] arr1 = {1,2,3};
    /* 
       Arrays are objects in Java, internally int[] will be represented by 
       an Integer Array object which when printed on console shall output
       a pattern such as 
       [I@address for 1-dim int array,
       [[I@address for 2-dim int array, 
       [[F@address for 2-dim float array etc. 
   */
    System.out.println(Arrays.asList(arr1)); 

    /* 
       The line below results in Compile time error as Arrays.asList(int[] array)
       returns List<int[]>. The returned list contains only one element 
       and that is the int[] {1,2,3} 
    */
    // List<Integer> list1 = Arrays.asList(arr1);

    /* 
       Arrays.asList(arr1) is  Arrays$ArrayList object whose only element is int[] array
       so the line below prints [[I@...], where [I@... is the array object.
    */
    System.out.println(Arrays.asList(arr1)); 

    /* 
     This prints [I@..., the actual array object stored as single element 
     in the Arrays$ArrayList object. 
    */
    System.out.println(Arrays.asList(arr1).get(0));

    // prints the contents of array [1,2,3]
    System.out.println(Arrays.toString(Arrays.asList(arr1).get(0)));

    Integer[] arr2 = {1,2,3};
    /* 
     Arrays.asList(arr) is  Arrays$ArrayList object which is 
     a wrapper list object containing three elements 1,2,3.
     Technically, it is pointing to the original Integer[] array 
    */
    List<Integer> list2 = Arrays.asList(arr2);

    // prints the contents of list [1,2,3]
    System.out.println(list2);
NINCOMPOOP answered 2019-08-13T09:49:57Z
translate from https://stackoverflow.com:/questions/16748030/difference-between-arrays-aslistarray-and-new-arraylistintegerarrays-aslist