使用Arrays.asList()的緣由無非是想將數組或一些元素轉爲集合,而你獲得的集合並不必定是你想要的那個集合。java
而一開始asList()的設計時用於打印數組而設計的,但jdk1.5開始,有了另外一個比較更方便的打印函數Arrays.toString(),因而打印再也不使用asList(),而asList()恰巧可用於將數組轉爲集合。面試
若是你這樣使用過,那你要注意下了。數組
將基本類型數組做爲asList的參數微信
int[] arr = {1,2,3}; List list = Arrays.asList(arr); System.out.println(list.size());
猜一下輸出結果?架構
將數組做爲asList參數後,修改數組或Listdom
String[] arr = {"歡迎","關注","Java"}; List list = Arrays.asList(arr); arr[1] = "愛上"; list.set(2,"我"); System.out.println(Arrays.toString(arr)); System.out.println(list.toString());
猜一下輸出結果?ide
數組轉換爲集合後,進行增刪元素函數
String[] arr = {"歡迎","關注","Java"}; List list = Arrays.asList(arr); list.add("新增"); list.remove("關注");
猜一下輸出結果?工具
你是否是覺得上面👆那個list是 java.util.ArrayList ?ui
答案很肯定:NO!
咱們經過asList()源碼可發現,但爲了更直觀,咱們經過IDEA debug來看看結果。
List<String> asList = Arrays.asList("歡迎","關注","碼上實戰"); ArrayList<String> aList = new ArrayList<>(asList);
其實它返回的是 java.util.Arrays.ArrayList
,這個傢伙是誰呢?
請看下源碼:
public class Arrays { //省略其餘方法 public static <T> List<T> asList(T... a) { return new ArrayList<>(a); } //就是這個傢伙 👇 private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable{ private final E[] a; ArrayList(E[] array) { a = Objects.requireNonNull(array); } @Override public int size() { return a.length; } //省略其餘方法 } }
但它和ArrayList貌似很像唉!有什麼不一樣嗎?
Arrays.ArrayList 是工具類 Arrays 的一個內部靜態類,它沒有徹底實現List的方法,而 ArrayList直接實現了List 接口,實現了List全部方法。
Arrays.ArrayList是一個定長集合,由於它沒有重寫add,remove方法,因此一旦初始化元素後,集合的size就是不可變的。
Arrays.ArrayList將外部數組的引用直接經過「=」賦予內部的泛型數組,因此本質指向同一個數組。
ArrayList(E[] array) { a = array; }
ArrayList是將其餘集合轉爲數組後copy到本身內部的數組的。
public ArrayList(Collection<? extends E> c) { // toArray 底層使用的是 數組clone 或 System.arraycopy elementData = c.toArray(); }
因爲Arrays.ArrayList參數爲可變長泛型,而基本類型是沒法泛型化的,因此它把int[] arr數組當成了一個泛型對象,因此集合中最終只有一個元素arr.
因爲asList產生的集合元素是直接引用做爲參數的數組,因此當外部數組或集合改變時,數組和集合會同步變化,這在平時咱們編碼時可能產生莫名的問題。
因爲asList產生的集合並無重寫add,remove等方法,因此它會調用父類AbstractList的方法,而父類的方法中拋出的倒是異常信息。
int[] a = {1,2,3}; List list = CollectionUtils.arrayToList(a); System.out.println(list);
int intArray[] = {1, 2, 3}; List<Integer> iList = Arrays.stream(intArray) .boxed() .collect(Collectors.toList()); System.out.println(iList);
Integer intArray[] = {1, 2, 3}; ArrayList<Integer> aList = new ArrayList<>(); for (Integer i: intArray){ aList.add(i); }
顯然這種方式不夠優雅!反正我不肯意使用。
上面方案不夠優雅,那麼這種相對來講優雅一些。
List<String> list = new ArrayList(); Collections.addAll(list, "welcome", "to", "china");
你覺得這種還不錯?
too young too simple!
addAll()方法的實現就是用的上面遍歷的方式。
既能夠用於基本類型也能夠返回想要的集合。
int intArray[] = {1, 2, 3}; List<Integer> iList = Arrays.stream(intArray) .boxed() .collect(Collectors.toList()); System.out.println(iList);
將Arrays.asList返回的集合做爲ArrayList的構造參數
ArrayList arrayList = new ArrayList<>(Arrays.asList("welcome", "to", "china"));
勿以點小而不聞!體現程序素養或許就在這些小地方,不要給本身或別人留坑。
那麼這個知識點,你get到了嗎?get到了,那來繼續關注我。沒get到?來來來,咱倆單獨聊聊。
關注微信公衆號 「碼上實戰」 回覆 :面試視頻 和 架構師 送你很是不錯的資料!