从数组创建列表

Arrays.asList() 方法可用于返回一个包含给定的阵列的元件固定大小 List。生成的 List 将与数组的基本类型具有相同的参数类型。

String[] stringArray = {"foo", "bar", "baz"};
List<String> stringList = Arrays.asList(stringArray);

注意 :此列表由原始数组的( 视图 ) 支持,这意味着对列表的任何更改都将更改数组,反之亦然。但是,对列表的更改将改变其大小(因此更改数组长度)将引发异常。

要创建列表的副本,请使用 java.util.ArrayList 的构造函数,将 Collection 作为参数:

Version >= Java SE 5

String[] stringArray = {"foo", "bar", "baz"};
List<String> stringList = new ArrayList<String>(Arrays.asList(stringArray));

Version >= Java SE 7

在 Java SE 7 及更高版本中,可以使用一对尖括号 <>(空类型参数集),称为 Diamond 。编译器可以从上下文中确定类型参数。这意味着在调用 ArrayList 的构造函数时可以省略类型信息,并且它将在编译期间自动推断。这称为 Type Inference ,它是 Java Generics 的一部分。

// Using Arrays.asList()

String[] stringArray = {"foo", "bar", "baz"};
List<String> stringList = new ArrayList<>(Arrays.asList(stringArray));

// Using ArrayList.addAll()

String[] stringArray = {"foo", "bar", "baz"};
ArrayList<String> list = new ArrayList<>();
list.addAll(Arrays.asList(stringArray));

// Using Collections.addAll()

String[] stringArray = {"foo", "bar", "baz"};
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, stringArray);

关于 Diamond 的一点值得注意的是它不能与 Anonymous Classes一起使用。

Version >= Java SE 8

// Using Streams

int[] ints = {1, 2, 3};
List<Integer> list = Arrays.stream(ints).boxed().collect(Collectors.toList());

String[] stringArray = {"foo", "bar", "baz"};
List<Object> list = Arrays.stream(stringArray).collect(Collectors.toList());

与使用 Arrays.asList() 方法相关的重要说明

  • 这个方法返回 List,这是 Arrays$ArrayList 的实例(Arrays 的静态内部类)而不是 java.util.ArrayList。由此产生的 List 具有固定的尺寸。这意味着,不支持添加或删除元素,并将抛出一个 UnsupportedOperationException

    stringList.add("something"); // throws java.lang.UnsupportedOperationException
    
  • 通过将支持数组的 List 传递给新 List 的构造函数,可以创建一个新的 List。这将创建一个新的数据副本,该副本具有可更改的大小,并且不受原始数组的支持:

    List<String> modifiableList = new ArrayList<>(Arrays.asList("foo", "bar"));
    
  • 在原始数组(例如 int[])上调用 <T> List<T> asList(T... a) 将产生一个 List<int[]>,其唯一的元素是源基本数组, 而不是源数组的实际元素。

    这种行为的原因是原始类型不能用于代替泛型类型参数,因此整个原始数组在这种情况下替换泛型类型参数。为了将原始数组转换为 List,首先,将原始数组转换为相应包装类型的数组(即在 Integer[] 上调用 Arrays.asList 而不是 int[])。

    因此,这将打印 false

    int[] arr = {1, 2, 3};      // primitive array of int
    System.out.println(Arrays.asList(arr).contains(1));
    

    查看演示

    另一方面,这将打印 true

    Integer[] arr = {1, 2, 3};  // object array of Integer (wrapper for int)
    System.out.println(Arrays.asList(arr).contains(1));
    

    查看演示

    这也将打印 true,因为该数组将被解释为 Integer[]):

    System.out.println(Arrays.asList(1,2,3).contains(1));
    

    查看演示