本篇隨筆主要描述的是我閱讀 ArrayList 源碼期間的對於 ArrayList 的一些實現上的個人理解,有不對的地方,請指出~
先來看一下 ArrayList 的繼承圖:

由圖可以看出,ArrayList 的父類有 AbstractList、 AbstractCollection ,所以我從 AbstractCollection 類開始閱讀。
一、AbstractCollection 類相關。
AbstractCollection 類實現了 Collection 接口,並且由於 AbstractCollection 是一個抽象類,所以它只實現了一些 Collection 接口中的方法,例如 toArray() 方法, contains() 方法, remove() 方法等等。對於Collection 接口中含有的其它方法仍令其保持抽象實現,我認為這樣實現的原因是 :抽象類的作用就是一個概括作用,它需要將其子類中含有的公共方法在抽象類中加以實現,而抽象類中仍然保持抽象的方法一般都是每個子類有自己的實現,在抽象類中是沒有辦法統一起來的。
在 AbstractCollection 類中,我以為 finishToArray() 方法值得注意一下:

finishToArray() 方法是用來給數組 r[] 擴容的,每次當數組 r 的容量不足以容納迭代器遍歷到的元素時,就會對數組 r 進行擴容,並且對擴容後的數組容量進行校驗(hugeCapacity())。
擴容方法:newCap = cap + (cap >> 1)+ 1;
二、AbstractList 相關
AbstractList 也是一個抽象類,其下面具體的子類主要有 LinkedList, ArrayList, Vector幾種。所以 AbstractList 中含有的方法主要是對這幾個具體的子類的抽象。
我認為 AbstractList 中主要有以下幾點值得注意:
1、AbstractList 中 iterator() 和 listIterator() 均采用內部類方式實現。
1 public Iterator<E> iterator() {
2 return new Itr();
3 }
4
5 public ListIterator<E> listIterator() {
6 return listIterator(0);
7 }
8
9 public ListIterator<E> listIterator(final int index) {
10 rangeCheckForAdd(index);
11
12 return new ListItr(index);
13 }
14
15 private class Itr implements Iterator<E> {
16
17 ......
18
19 }
20
21 private class ListItr extends Itr implements ListIterator<E> {
22 ......
23 }
2、AbstractList 中 removeRange() 方法為我們展示了如何運用迭代器移除 list 指定范圍的元素。
1 protected void removeRange(int fromIndex, int toIndex) {
2 ListIterator<E> it = listIterator(fromIndex);
3 for (int i=0, n=toIndex-fromIndex; i<n; i++) {
4 it.next();
5 it.remove();
6 }
7 }
3、並發修改異常 ConcurrentModificationException
在 AbstractList 中通過 expectedModCount 和 modCount 兩個量比較來判斷是否產生了並發修改異常,當迭代器在迭代過程中發現 expectedModCount 和 modCount 兩個量不相 等時就會拋出並發修改異常。modCount 代表改動 list 的次數,當獲得一個 iterator 或者 listIterator 時,就會將 modCount 值賦給 expectedModCount,在迭代器使用的過程中,如果出 現兩個值不相等的情況 ,就證明有迭代器之外的操作改動了 list,而這很可能會導致迭代器對 list 的操作出現錯誤,所以在接下來使用迭代器的時候就會拋出異常,這就是並發修改異 常的作用。
4、AbstractList 中的 subList() 方法。
先來看下 subList() 方法的實現:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
......
public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<>(this, fromIndex, toIndex) :
new SubList<>(this, fromIndex, toIndex));
}
......
}
class SubList<E> extends AbstractList<E> {
SubList(AbstractList<E> list, int fromIndex, int toIndex) {
l = list;
offset = fromIndex;
size = toIndex - fromIndex;
this.modCount = l.modCount;
}
public E set(int index, E element) {
return l.set(index+offset, element);
}
......
}
class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
super(list, fromIndex, toIndex);
}
......
}
可見有 SubList 與 RandomAccessSubList 兩種,區別在於是否實現 RandomAccess 接口 ,也就是是否可以隨機讀取,例如 ArrayList 可以隨機讀取,而 LinkedList 則只能順序讀 取。在SubList類的構造方法中,獲取了一個 AbstractList 類的引用,作用是利用這個引用實現 SubList 中的相關方法。
也就是說,subList 幾乎所有方法都是基於 AbstractList 類實現的,對於 subList 返回的 list 所做的所有改動都會反應到原來的 list 當中去。
三、ArrayList 相關