Java中List.of与Arrays.asList的区别
前言
Java中List.of和Arrays.asList都可以用来快速创建一个List容器
在Java中List.of
和Arrays.asList
都可以用来快速创建一个List
容器
1 2 3
| List<Integer> list1 = List.of(1, 2, 3); List<Integer> list2 = Arrays.asList(1, 2, 3);
|
1 2 3 4
| Integer[] ints = {4, 5, 6}; List<Integer> list1 = List.of(ints); List<Integer> list2 = Arrays.asList(ints);
|
原文地址:https://xuedongyun.cn/post/8447/
区别
List.of
和Arrays.asList
的区别在于:
| List.of | Arrays.asList |
---|
能否包含null | 不可以 | 可以 |
能否修改 | 不可以 | 可以 |
修改原数组是否影响List | 不影响 | 影响 |
List.of不能包含null的原因
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @SafeVarargs @SuppressWarnings("varargs") static <E> List<E> of(E... elements) { switch (elements.length) { case 0: @SuppressWarnings("unchecked") var list = (List<E>) ImmutableCollections.EMPTY_LIST; return list; case 1: return new ImmutableCollections.List12<>(elements[0]); case 2: return new ImmutableCollections.List12<>(elements[0], elements[1]); default: return ImmutableCollections.listFromArray(elements); } }
|
1 2 3 4 5 6 7 8 9 10
| @SafeVarargs static <E> List<E> listFromArray(E... input) { E[] tmp = (E[])new Object[input.length]; for (int i = 0; i < input.length; i++) { tmp[i] = Objects.requireNonNull(input[i]); } return new ListN<>(tmp, false); }
|
List.of不能修改的原因
1 2 3 4 5 6 7 8
| @Stable private final E[] elements;
private ListN(E[] elements, boolean allowNulls) { this.elements = elements; this.allowNulls = allowNulls; }
|
原数组是否影响List的原因
对List.of
而言,底层创建了新的new Object[]
,所以修改数组不影响List
1 2 3 4 5 6 7 8 9 10
| @SafeVarargs static <E> List<E> listFromArray(E... input) { E[] tmp = (E[])new Object[input.length]; for (int i = 0; i < input.length; i++) { tmp[i] = Objects.requireNonNull(input[i]); } return new ListN<>(tmp, false); }
|
对Arrays.asList
而言,直接使用了传入的数组作为底层存储,所以修改数组影响List
1 2 3
| public static <T> List<T> asList(T... a) { return new ArrayList<>(a); }
|
1 2 3
| ArrayList(E[] array) { a = Objects.requireNonNull(array); }
|
1 2 3 4 5 6
| public static <T> T requireNonNull(T obj) { if (obj == null) throw new NullPointerException(); return obj; }
|
Arrays.asList常见错误
Arrays.asList修改
Arrays.asList()
返回的是一个固定大小的List,这个List对象是通过Arrays内部类ArrayList(也叫ArrayList!)创建的
这个List不支持修改元素大小(add和remove方法),修改会报异常: java.lang.UnsupportedOperationException
原因:Arrays
内部类ArrayList
其实是直接使用了原始的数组,因为共享了数组,相互修改容易产生 Bug
1 2 3 4
| List<Integer> list = Arrays.asList(1, 2, 3);
list.add(222);
|
解决方法1:使用ArrayList来进行转换
1 2 3
| Integer[] ints = {1, 2, 3}; List<Integer> list = Arrays.asList(ints); ArrayList<Integer> list1 = new ArrayList<>(list);
|
解决方法2:使用Collections.addAll()
1 2 3
| Integer[] ints = {1, 2, 3}; ArrayList<Integer> list = new ArrayList<>(ints.length); Collections.addAll(list, ints);
|
解决方法3:使用Stream
1 2
| Integer[] ints = {1, 2, 3}; List<Integer> list = Stream.of(ints).toList();
|
原生类型数组作为参数
asList
方法的签名为:public static <T> List<T> asList(T... a)
,需要匹配参数类型T,但是原生属性是没有这个类型的。所以当传入一个原生数据类型数组时,asList得到的真正参数不是数组中的元素,而是数组本身!
1 2 3 4
| int[] ints = {1, 2, 3};
List<int[]> list = Arrays.asList(ints);
|
解决方法:使用包装类数组
1 2
| Integer[] ints = {1, 2, 3}; List<Integer> list = Arrays.asList(ints);
|