Java9 List.of() 对比 Arrays.asList()

本文内容部分节选自:

https://blog.csdn.net/weixin_46937640/article/details/119612369

https://www.cnblogs.com/Ga7l/p/14430303.html

https://blog.csdn.net/qq_42520962/article/details/109380430

 

jdk9的新特性

List接口,Set接口,Map接口:里面增加了一个静态的方法of,可以给集合一次性添加多个元素

使用前提:

       当集合中存储的元素个数已经确定了,不再改变时使用。

注意:

       1.of方法只适用于List接口,Set接口,Map接口,不适用于接口的实现类

       2.of方法的返回值是一个不能改变的集合,集合不能再使用add,put方法添加元素,会抛出异常

       3.Set接口和Map接口在调用of方法的时候,不能有重复的元素,否则会抛出异常

//在对列表中下标元素进行修改时
//list.of生产的列表会出现异常
List<String> strings = Arrays.asList("demo1", "demo2", "demo3");
List<String> demo1 = List.of("demo1", "demo2", "demo3");

strings.set(1,"bambi1"); demo1.set(1,"bambi1");//会出现UnsupportedOperationException异常 strings.set(1,"bambi1"); demo1.set(1,"bambi1");//会出现UnsupportedOperationException异常

//list.of生成的列表中,元素不可以为null,不然会报空指针异常 List<String> bambi11 = Arrays.asList("bambi1", null); List<String> bambi1 = List.of("bambi1", null, "bambi2");//NullPointerException

同理,如果使用contains方法来检测是否存在null值,List.of列表也会爆出空指针异常

 

 

Arrays.asList() 和 List.of()的区别

1.Arrays.asList()可以插入null,而List.of()不可以

import java.util.List;
import java.util.Arrays;

class Solution {
  public static void main(String[] args) {
    List<Integer> ls1 = Arrays.asList(1, 2, null);
    //List<Integer> ls2 = List.of(1,2,null);
    System.out.println(ls1);
    //System.out.println(ls2);
  }
}
/*结果 [1, 2, null] */
import java.util.List;
import java.util.Arrays;

class Solution {
  public static void main(String[] args) {
    //List<Integer> ls1 = Arrays.asList(1, 2, null);
    List<Integer> ls2 = List.of(1,2,null);
    //System.out.println(ls1);
    System.out.println(ls2);
  }
}

/*结果
Exception in thread "main" java.lang.NullPointerException.....
*/

2.用List.of的List自然是不包含null,而用Arrays.asList的List包含null。上图结果也可得知。

import java.util.List;
import java.util.Arrays;

class Solution {
  public static void main(String[] args) {
    List<Integer> ls1 = Arrays.asList(1, 2, null);
    //List<Integer> ls2 = List.of(1,2);
    System.out.println(ls1.contains(null));
    //System.out.println(ls2.contains(null));
  }
}

/*结果
true
*/
import java.util.List;
import java.util.Arrays;

class Solution {
  public static void main(String[] args) {     //List<Integer> ls1 = Arrays.asList(1, 2, null);     List<Integer> ls2 = List.of(1,2);     //System.out.println(ls1.contains(null));     System.out.println(ls2.contains(null));   } } /*结果 Exception in thread "main" java.lang.NullPointerException..... */

3.List.of生成的List不能修改,Arrays.asList生成的List能修改。

import java.util.List;
import java.util.Arrays;

class Solution {
  public static void main(String[] args) {
    List<Integer> ls1 = Arrays.asList(1, 2, null);
    //List<Integer> ls2 = List.of(1,2);
    ls1.set(0,5);
    //ls2.set(0,5);
    System.out.println(ls1);
    //System.out.println(ls2);
  }
}

/*结果
[5, 2, null]
*/
import java.util.List;
import java.util.Arrays;

class Solution {
    public static void main(String[] args) {
        //List<Integer> ls1 = Arrays.asList(1, 2, null);
        List<Integer> ls2 = List.of(1,2);
        //ls1.set(0,5);
        ls2.set(0,5);
        //System.out.println(ls1);
        System.out.println(ls2);
    }
}

/*结果
Exception in thread "main" java.lang.UnsupportedOperationExceptio.....
*/

4.关于数组修改对List的影响。数组修改对Arrays.asList生成的List有影响,对List.of 生成的List无影响

import java.util.List;
import java.util.Arrays;

class Solution {
  public static void main(String[] args) {
    Integer[] a = new Integer[]{1,2,3,4};
    // 不能用int[],会导致转型错误,错误: 不兼容的类型: 推论变量 T 具有不兼容的上限
    List<Integer> ls1 = Arrays.asList(a);
    //List<Integer> ls2 = List.of(a);
    System.out.println(ls1);
    //System.out.println(ls2);
    a[0] = 5;
    //ls2.set(0,5);
    System.out.println(ls1);
    //System.out.println(ls2);
  }
}

/*结果
[1, 2, 3, 4]
[5, 2, 3, 4]
*/
import java.util.List;
import java.util.Arrays;

class Solution {
  public static void main(String[] args) {
    Integer[] a = new Integer[]{1,2,3,4};
    //List<Integer> ls1 = Arrays.asList(a);
    List<Integer> ls2 = List.of(a);
    //System.out.println(ls1);
    System.out.println(ls2);
    a[0] = 5;
    //ls2.set(0,5);
    //System.out.println(ls1);
    System.out.println(ls2);
  }
}

/*结果
[1, 2, 3, 4]
[1, 2, 3, 4]
*/

 

原因

关于List.of为什么不能插入null,和修改了原数组不影响到List.of生成的List。先看看List.of有关的源码

@SafeVarargs
@SuppressWarnings("varargs")
    static <E> List<E> of(E... elements) {
        switch (elements.length) { // implicit null check of elements
        case 0:
        return ImmutableCollections.emptyList();
        case 1:
        return new ImmutableCollections.List12<>(elements[0]);
        case 2:
        return new ImmutableCollections.List12<>(elements[0], elements[1]);
        default:
        return new ImmutableCollections.ListN<>(elements);
    }
}

//---------------------------------------------------------------------------------------
@Stable
private final E[] elements;

@SafeVarargs
ListN(E... input) {
    // copy and check manually to avoid TOCTOU
    @SuppressWarnings("unchecked")
    E[] tmp = (E[])new Object[input.length]; // implicit nullcheck of input
    for (int i = 0; i < input.length; i++) {
        tmp[i] = Objects.requireNonNull(input[i]);
    }
    elements = tmp;
}

//---------------------------------------------------------------------------------------
public static <T> T requireNonNull(T obj) {
    if (obj == null)
    throw new NullPointerException();
    return obj;
}

可以看到Objects.requireNonNull()。所以不能插入空值。

E[] tmp = (E[])new Object[input.length];表示新建了个新的数组对象,所以修改了原数组,不影响生成的LIst底层的数组。

返回的数组是个final类型的,所以不能修改

再看看Arrays.asList源码

@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

//----------------------------------------------------------------------------------------
ArrayList(E[] array) {
    a = Objects.requireNonNull(array);
}

//----------------------------------------------------------------------------------------
public static <T> T requireNonNull(T obj) {
    if (obj == null)
    throw new NullPointerException();
    return obj;
}

由源码可知,底层的数组就是传入的数组,所以对原数组的修改会影响到用Arrays.asList方法生成的List。而且Objects.requireNonNull(array)检查的是整个数组是不是null,而非对每个元素进行检查是否为null。所以用Arrays.asList方法可以插入空值。

也没有规定是final的,所以支持修改。

posted @ 2023-06-20 10:37  YukiRinLL  阅读(15)  评论(0编辑  收藏  举报