软件编程
位置:首页>> 软件编程>> java编程>> Java中List.of()和Arrays.asList()的区别及原因分析

Java中List.of()和Arrays.asList()的区别及原因分析

作者:爱唱歌的瓜皮  发布时间:2023-08-06 00:33:16 

标签:Java,List.of,Arrays.asList

Java中List.of()和Arrays.asList()的区别及原因

动手写一下,让自己更有印象

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的,所以支持修改。

java listof报错处理

List.of()生成不可变数组(字符串也行)

是在jdk1.8以后才出现的,在jdk1.9版本及以后才能运行。

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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com