1. 程式人生 > >JDK之ArrayList原始碼解讀(二)

JDK之ArrayList原始碼解讀(二)

目錄

 

remove(int index)

remove(Object o)

clear()

addAll(Collection c)

addAll(int index, Collection c)

removeRange(int fromIndex, int toIndex)


remove(int index)

public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

作用:刪除索引位置處的元素。

先檢查索引是否合法,然後modCount加1。然後獲取index位置上原有的元素的值,最後返回該值。

通過System.arraycopy方法,將ArrayList的陣列中index位置的後一位到陣列結束的所有元素都向左移動一位,同時將陣列的最後一個位置設定為null,方便GC進行回收。

remove(Object o)

public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

作用:刪除ArrayList中值等於Object o的第一元素。

當Object o為null時,遍歷陣列,當遇到第一個值為null的時候,呼叫fastRemove刪除該值,並將所有後面的元素往前移動一位。

private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work
    }

fastRemove的作用於前面的remove(int index)方法作用類似,只是少了引數的校驗和返回值。

當Object o不為null時,遍歷陣列,當遇到第一個值等於Object o的時候,呼叫fastRemove刪除該值,並將所有後面的元素往前移動一位。

clear()

public void clear() {
        modCount++;

        // clear to let GC do its work
        for (int i = 0; i < size; i++)
            elementData[i] = null;

        size = 0;
    }

作用:清空ArrayList中的所有元素。

遍歷陣列,將所有位置的值都設定成null,便於GC,同時將ArrayList元素個數歸0。

addAll(Collection<? extends E> c)

public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }

作用:將Collection c中的元素加入ArrayList的末尾。

先將Collection c轉換成陣列,再將Collection c中所有元素個數加上ArrayList元素的個數,與陣列的容量對比,根據結果來判斷陣列是否需要擴容。然後利用native方法System.arraycopy(),將Collection c的元素複製到ArrayList的尾部,ArrayList元素的個數size要加上Collection c的元素個數。

addAll(int index, Collection<? extends E> c)

public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index);

        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount

        int numMoved = size - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,
                             numMoved);

        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }

作用:將Collection c中的元素加入ArrayList中指定的位置上。

先使用rangeCheckForAdd()校驗索引的合法性。再將Collection c轉換成陣列,再將Collection c中所有元素個數加上ArrayList元素的個數,與陣列的容量對比,根據結果來判斷陣列是否需要擴容。然後利用native方法System.arraycopy(),將陣列中index索引處往後數c.length個元素,往後移動。然後將Collection c的元素放入陣列中空出來的那些位置上。

removeRange(int fromIndex, int toIndex)

protected void removeRange(int fromIndex, int toIndex) {
        modCount++;
        int numMoved = size - toIndex;
        System.arraycopy(elementData, toIndex, elementData, fromIndex,
                         numMoved);

        // clear to let GC do its work
        int newSize = size - (toIndex-fromIndex);
        for (int i = newSize; i < size; i++) {
            elementData[i] = null;
        }
        size = newSize;
    }

作用:刪除ArrayList中兩個位置中間的所有元素。

將陣列中從toIndex位置到結尾處的所有元素,移動到fromIndex位置處。然後將陣列中從末尾往前數,數出(toIndex-fromIndex)個位置,將他們設定成null,便於GC。新ArrayList的元素個數重新賦值。