[TOC]java
1. 概述
在使用List集合時有些地方須要注意一下的, 否則會出現一些莫名其妙的錯誤.數組
2. Arrays.asList();
2-1. 產生不可操做的集合
來看一個例子.dom
Integer[] array = {1, 2, 3, 4, 5}; List<Integer> list = Arrays.asList(array); list.remove(1);
會直接拋出java.lang.UnsupportedOperationException異常, 爲何呢?ui
答案是: 返回的List非java.util.ArrayList. 而是在Arrays類內部有一個靜態內部類叫ArrayList.spa
靜態內部類ArrayList並無提供全部的方法實現, 有些方法在抽象類中僅僅是一個拋異常的實現, 上述的remove就是這種狀況. asList返回的列表只不過是披着list的外衣, 它並無list的基本特性(變長), 該list是一個長度不可變的列表, 傳入參數的數組有多長, 其返回的列表就只能是多長. 因此不要試圖改變asList的返回列表.code
Arrays.asList的代碼以下:對象
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 static final long serialVersionUID = -2764017481108945198L; private final E[] a; ArrayList(E[] array) { a = Objects.requireNonNull(array); } // 省略部分源碼 }
該類也是繼承了AbstractkList抽象類, 只是該類並無提供全部方法的實現.繼承
2-2. 須要傳入對象數組而不是基本類型數組
看個例子:rem
int[] array1 = {1, 2, 3, 4, 5}; List<int[]> list1 = Arrays.asList(array1); System.out.println(list1.size()); // 1 Integer[] array2 = {1, 2, 3, 4, 5}; List<Integer> list2 = Arrays.asList(array2); System.out.println(list2.size()); // 5
看到Array.asList的返回值的泛型就明白, list1中存儲的實際是一個數組. 爲何這樣呢? 數值類型不能被泛型化, 好比List<int>
是不對的, 必須是List<Integer>
纔對.源碼
3. arrayList.subList();
3-1. subList返回的並非ArrayList
方法返回的是一個內部類SubList, 並非ArrayList, SubList也是繼承AbstractList, 內部引用了原列表的List.
3-2. subList返回的僅僅是一個視圖
subList返回的僅僅是一個視圖, 對subList返回值的全部操做都會做用在原列表中.
看一個例子
List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); list.add("D"); list.add("E"); List<String> subList = list.subList(2, 4); subList.add("F"); System.out.println(list); // 輸出 [A, B, C, D, F, E]
經過輸出結果可知, F被添加到原列表中了.
3-3. 生成子列表時, 不要試圖去操做原列表
由於子列表是根據原列表動態生成的, 因此若是原列表變了, 那麼操做子列表時就會發生ConcurrentModificationException異常. 這個異常的緣由相信你也知道, 就是modCount改變了致使的.
3-4. 推薦使用subList處理局部鏈表
好比, 有一個需求要刪除列表100-200位置處的數據, 一般咱們這樣寫:
int start = 100; int end = 200; for (int i = start; i <= end; i++) { list.remove(start); }
經過subList, 咱們有一個更簡潔的處理方式:
list.subList(100, 200).clear();
簡潔.
不按期更新
可能還會遇到集合相關的坑.