將陣列轉換成集合Arrays.asList,不可進行add和remove操作的原因
直接上程式碼:
import java.util.Arrays; import java.util.List; public class Test { public static void main(String[] args) { Integer a[] = {1,2,5,6,9}; List<Integer> list = Arrays.asList(a); System.out.println(list.size()); list.add(3); System.out.println(list.size()); } }
執行結果:
原因看原始碼:
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
new了一個ArrayList集合,注意了,這個可不是ArrayList類,而是Arrays裡面的一個靜態內部類
內部類原始碼給出來參考:
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable { private static final long serialVersionUID = -2764017481108945198L; private final E[] a; ArrayList(E[] array) { a = Objects.requireNonNull(array); } @Override public int size() { return a.length; } @Override public Object[] toArray() { return a.clone(); } @Override @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { int size = size(); if (a.length < size) return Arrays.copyOf(this.a, size, (Class<? extends T[]>) a.getClass()); System.arraycopy(this.a, 0, a, 0, size); if (a.length > size) a[size] = null; return a; } @Override public E get(int index) { return a[index]; } @Override public E set(int index, E element) { E oldValue = a[index]; a[index] = element; return oldValue; } @Override public int indexOf(Object o) { E[] a = this.a; if (o == null) { for (int i = 0; i < a.length; i++) if (a[i] == null) return i; } else { for (int i = 0; i < a.length; i++) if (o.equals(a[i])) return i; } return -1; } @Override public boolean contains(Object o) { return indexOf(o) != -1; } @Override public Spliterator<E> spliterator() { return Spliterators.spliterator(a, Spliterator.ORDERED); } @Override public void forEach(Consumer<? super E> action) { Objects.requireNonNull(action); for (E e : a) { action.accept(e); } } @Override public void replaceAll(UnaryOperator<E> operator) { Objects.requireNonNull(operator); E[] a = this.a; for (int i = 0; i < a.length; i++) { a[i] = operator.apply(a[i]); } } @Override public void sort(Comparator<? super E> c) { Arrays.sort(a, c); } }
內部類沒有add和remove當然不能進行這些操作了,但是修改set還是可以的。
官方文件解釋:
asList
public static <T> List<T> asList(T... a)
返回一個受指定陣列支援的固定大小的列表。(對返回列表的更改會“直接寫”到陣列。)此方法同 Collection.toArray() 一起,充當了基於陣列的 API 與基於 collection 的 API 之間的橋樑。返回的列表是可序列化的,並且實現了 RandomAccess。
此方法還提供了一個建立固定長度的列表的便捷方法,該列表被初始化為包含多個元素:
List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
引數:
a - 支援列表的陣列。
返回:
指定陣列的列表檢視。
用asList轉換的程式碼是返回List的實現類ArrayList集合物件
但是集合大小固定,無法新增和刪除
如果想要將陣列轉換成一個可以具有正常新增和刪除操作的List話,
一種情況就是遍歷陣列,一個個新增到list中
或者用Collections.addAll(list, a);
又或者直接new ArrayList<...>(Arrays.asList(a))放入另一個ArrayList
關於Collections.addAll文件顯示:
addAll
public static <T> boolean addAll(Collection<? super T> c,
T... elements)
將所有指定元素新增到指定 collection 中。可以分別指定要新增的元素,或者將它們指定為一個數組。此便捷方法的行為與 c.addAll(Arrays.asList(elements)) 的行為是相同的,但在大多數實現下,此方法執行起來可能要快得多。
在分別指定元素時,此方法提供了將少數元素新增到現有 collection 中的一個便捷方式:
Collections.addAll(flavors, "Peaches 'n Plutonium", "Rocky Racoon");
引數:
c - 要插入 elements 的 collection
elements - 插入 c 的元素
返回:
如果 collection 由於呼叫而發生更改,則返回 true
丟擲:
UnsupportedOperationException - 如果 c 不支援 add 操作
NullPointerException - 如果 elements 包含一個或多個 null 值並且 c 不允許使用 null 元素,或者 c 或 elements 為 null
IllegalArgumentException - 如果 elements 中值的某個屬性不允許將它新增到 c 中
從以下版本開始:
1.5
另請參見:
Collection.addAll(Collection)
文件寫出如果第一個引數集合c如果不支援add操作仍然丟擲UnsupportedOperationException,就比如剛剛用一個數組List<Integer> list = Arrays.asList(a);此時的list不允許add操作,會丟擲UnsupportedOperationException,同樣的,此時再進行Collections.addAll(list, a);也是會丟擲UnsupportedOperationException。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Test {
public static void main(String[] args) {
Integer a[] = {1,2,5,6,9};
List<Integer> list = new ArrayList<>();
System.out.println(list.size());
Collections.addAll(list, a);
list.add(3); // 此時的新增是可以成功的
System.out.println(list.size());
}
}
執行結果:
附贈一個踩坑題:
import java.util.Arrays;
import java.util.List;
public class Test {
public static void main(String[] args) {
int[] a = new int[] { 1, 2, 3, 4 };
List list = Arrays.asList(a);
System.out.println(list.size());
}
}
這個程式輸出是什麼???
是4嗎???
執行結果是1
看一下原始碼:
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
因為基本型別是不能做泛型引數的,這裡的a接收引用型別,即List<int[]> list = Arrays.asList(a);
就是1個int[]陣列。要想解決這個問題,將int[]改為Integer[]即可,那麼答案就是4了。
==========================Talk is cheap, show me the code==========================