1. 程式人生 > >util集合類SubList原始碼分析

util集合類SubList原始碼分析

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變得不可