天天看點

一步一步解析集合架構ArrayList源碼(2)

我在閱讀源碼的過程中很多時候是沒有頭緒的。是以為了避免大家也遇到這種狀況,源碼不求全求大,做到“透過實踐看源碼”,分塊分層。

首先對ArrayList做個總體介紹:

ArrayList的底層存儲結構是數組,實際上在這個類中真正儲存資料的是内部定義的一個數組,自身的資料操作隻是封裝了數組的操作!
           
  • 修改集合元素
public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<String>();
        list.add("first");
        list.add("second");
        String ele1=list.get();
        System.out.println(ele1);
        list.set(,"第一個");
        System.out.println(list.get());
    }
           

輸出結果: first

第一個

源碼分析:

/**
     * 替換,設定;
     * 将索引index的元素值設定為element
     * 傳回原索引的元素值
     */
    public E set(int index, E element) {
        rangeCheck(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }
           
  • 删除集合元素
public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<String>();
        list.add("first");
        list.add("second");
        System.out.println(list.remove());
        System.out.println(list.get());
    }
           

輸出結果:

second
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: , Size: 
           

說明删除成功,已經不存在”second”的元素值。

源碼分析:

/**
     *通過索引删除元素,傳回删除的元素值
     */
    public E remove(int index) {
        rangeCheck(index);

        modCount++;
        //删除前的索引元素值
        E oldValue = elementData(index);
        //計算要複制的長度,即從index+1至最後一個元素共計多少
        int numMoved = size - index - ;
        if (numMoved > )
       /**
        * 第一個參數:原數組,
        * 第二個參數:複制開始索引,
        * 第三個參數:目标數組,
        * 第四個參數:目标數組複制開始索引,
        * 第五個參數:複制長度
        */
             System.arraycopy(elementData, index+, elementData, index, numMoved);
        //清空最後一個元素值
        elementData[--size] = null; 

        return oldValue;
    }
           
/**
     *根據元素值進行删除
     */
    public boolean remove(Object o) {
        //周遊數組elementData,比較進行删除
        if (o == null) {
            for (int index = ; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = ; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

    /*
     * 私有方法;
     * 删除索引index元素值
     */
    private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - ;
        if (numMoved > )
            System.arraycopy(elementData, index+, elementData, index,
                             numMoved);
        elementData[--size] = null; 
    }
           

繼續閱讀