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

  • 18
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值