util集合類SubList原始碼分析
阿新 • • 發佈:2019-07-01
SubList繼承AbstractList抽象類,AbstractList實現了List介面,所以SubList說到底就是一個List的實現類。
SubList是通過subList()方法返回的物件,主要用於返回一個List集合的其中一部分檢視。
SubList的建構函式:
SubList(AbstractList<E> list, int fromIndex, int toIndex) { if (fromIndex < 0) throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); if (toIndex > list.size()) throw new IndexOutOfBoundsException("toIndex = " + toIndex); if (fromIndex > toIndex) throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); l = list; offset = fromIndex; size = toIndex - fromIndex; this.modCount = l.modCount; }
通過建構函式中可以看出,生成SubList的時候,會把之前的List作為Parent屬性,並且會把Parent的modCount作為自身的modCount。
再看List的2個比較重要的方法:
public void add(int index, E element) { rangeCheckForAdd(index); checkForComodification(); l.add(index+offset, element); this.modCount = l.modCount; size++; } public E remove(int index) { rangeCheck(index); checkForComodification(); E result = l.remove(index+offset); this.modCount = l.modCount; size--; return result; }
通過add和remove方法可以看出,當我們試圖對SubList進行修改的時候,那麼也會同時對Parent進行一樣的修改。
再看add和remove都同時呼叫的checkForComodification方法:
private void checkForComodification() {
if (this.modCount != l.modCount)
throw new ConcurrentModificationException();
}
方法裡面判斷SubList的modCount是否被修改過,它使用的是Parent的modCount,那麼如果當Parent進行了add和remove等操作,那麼SubList進行add和remove操作的時候,會丟擲ConcurrentModificationException異常。
因此,對於使用SubList總結幾點:
1.SubList應該僅僅作為試圖使用,謹慎對他進行任何的add和remove操作,因為無法確保Parent是否有改動過
2.當SubList進行改動的時候,Parent會同時進行改動操作
3.當Parent進行改動操作之後,之前返回的SubList變得不可