java基礎-ArrayList源碼分析

1.ArrayList arraylist能夠說是java開發者用過最多的集合了,應該沒有之一吧?閒話少說,直接上代碼java

private transient Object[] elementData;
private int size;

經過上面這行咱們認識到ArrayList的本質其實就是一個數組,而且提供了一個size屬性來保存集合中元素的個數。數組

public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
    }

    public ArrayList() {
        this(10);
    }

這裏貼出兩個構造方法,很好理解,若是構造時傳入int類型的參數一個,那麼就建立一個initialCapacity大小的數組,若是使用無參構造函數,則默認初始化一個長度爲10的數組函數

下面開始將有針對性的分析幾個經常使用的方法,如add、remove、get等this

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    private void ensureCapacityInternal(int minCapacity) {
        modCount++;
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

這裏給出了和add方法相關的全部函數,邏輯很簡單,進入add方法後先判斷容量,調用ensureCapacityInternal(size + 1)確保數組還有空閒空間可以再存放一個元素。 當元素個數即size+1大於數組長度,其實至關於元素個數等於數組長度,即數組已滿,調用grow函數來擴展數組長度。 grow中的邏輯也很容易理解,(oldCapacity >> 1)至關於(oldCapacity / 2),即默認擴大到元長度的1.5倍,下面就是檢查這個新長度是否符合邏輯,最後使用Arrays.copyOf來擴容code

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; // Let gc do its work

        return oldValue;
    }

rangeCheck檢查傳入的參數,大於size會拋出異常。if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index,numMoved);若是刪除的不是最後一個元素,將elementData數組index後面的元素向前移動一位,因爲System.arraycopy調用的是本地方法,因此看不到源碼ci

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

        return elementData(index);
    }

get方法的代碼更簡單,判斷index在正確範圍以後直接使用數組下標取值。在這裏也體現出了ArrayList的優點,快速訪問。這裏就簡單介紹ArrayList的基本操做,有興趣的同窗能夠自行閱讀源碼element

相關文章
相關標籤/搜索