關於Arrays.asList返回的List無法新增和刪除?
這個是在寫專案的時候發現的,然後就分析了一下原始碼,得其內部原理
復現程式碼示例:
public class ArraysAsList {
public static void main(String[] args) {
Integer[] array = {1, 2, 3, 4, 5};
List<Integer> list = Arrays.asList(array);
list.forEach(System.out::println);
list.add(11);
}
}
程式執行至list.add(11)時報錯
Exception in thread "main" java.lang.UnsupportedOperationException
分析原始碼:
點選檢視Arrays.asList原始碼,靜態的返回 List
看一下asList裡面 new ArrayList的程式碼實現,就會發現這裡的ArrayList並不是java.util.ArrayList中的單列集合,而是Arrays工具類(java.util.Arrays)中的靜態內部類ArrayList
然後迴歸到Arrays.asList()方法,為什麼這個方法生成的List集合無法在add和remove
因為這裡返回的是一個 final 陣列,陣列本身就是不可變的,所以當呼叫Arrays.asList方法返回一個集合後,無法在對這個集合進行一些操作,這個是陣列的特性
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
至於為什麼java.util包下的ArrayList的底層也是陣列,但是它依然可以去add和remove,那是因為它的add和remove方法copy了新的陣列,但是在Arrays下面的ArrayList靜態內部類中,它並沒有實現add和remove方法用來對集合進行新增和刪除,如下所示:
也就是說我們可以呼叫get方法得到Arrays.asList返回的集合元素,也可以set修改這裡面的值,但是因為它沒有add和remove方法所以無法對集合進行增加和刪除,這也是為什麼會報錯:UnsupportedOperationException(沒有支援的方法)的原因。
至此我認為Arrays.asList的問題就講完了,但是在寫這個示例的時候我發現了一個新的知識函式式介面,之前瞭解過,但是不是很熟悉。
如果你是為了明白Arrays.asList的問題,那麼到這裡就可以止步了。