Jdk8集合源碼解析---ArrayList

    ArrayList的數據結構java

    ArrayList是一種線性數據結構,底層是動態數組實現的,與java中的數組相比,它的容量能夠動態添加。數組

    ArrayList的類結構數據結構

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
      ......

}

    ArrayList的主要成員變量dom

//默認容量
private static final int DEFAULT_CAPACITY = 10;

private static final Object[] EMPTY_ELEMENTDATA = {};

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

//ArrayList存儲數據的數組
transient Object[] elementData;

//存儲元素數目
private int size;

//默認最大容量數目
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

//
protected transient int modCount = 0;

    ArrayList的構造方法this

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

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

    ArrayList的主要方法code

    存:ci

    boolean add(E e);element

public boolean add(E e) {
        //根據當前下角標size+1和當前數組的容量,判斷是否須要擴容,若是須要,擴容到1.5倍
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //將新元素加入數組中,下角標爲size+1
        elementData[size++] = e;
        return true;
}

private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //若是存儲元素的數組爲空,容量值爲10和minCapacity中的較大者
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
        //更新次數加一
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            //若是minCapacity大於當前數組的長度,擴容
            grow(minCapacity);
}

private void grow(int minCapacity) {
        //將當前數組的長度賦值給oldCapacity
        int oldCapacity = elementData.length;
        //新的容量值爲原來的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            //若是新容量值比minCapacity 值小,新容量值即爲minCapacity
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            //若是新容量值大於容許的最大長度
            newCapacity = hugeCapacity(minCapacity);
        //根據容量建立一個新數組,並將舊數組的元素複製給新數組
        elementData = Arrays.copyOf(elementData, newCapacity);
}

private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            //若是minCapacity小於零,直接拋出OOM異常
            throw new OutOfMemoryError();
        //若是minCapacity大於最大數組容量,則返回Integer的最大值,不然返回
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
}

    

    void add(int index,E e);rem

public void add(int index, E element) {
        //校驗下角標index是否越界
        rangeCheckForAdd(index);
        //判斷是否須要擴容
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //將當前數組中下角標爲[index,size]的元素複製到[index+1,size+1]的位置
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        //將element放置到數組下角標爲index的位置
        elementData[index] = element;
        //數組內元素個數加1
        size++;
}

private void rangeCheckForAdd(int index) {
        if (index > size || index < 0)
            //若是index大於數組元素的個數,或者index<0,拋出下角標越界異常
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

    E  set(int index,E e);get

public E set(int index, E element) {
        //校驗下角標是否越界
        rangeCheck(index);
        //將數組中下角標爲index的元素賦值給oldValue
        E oldValue = elementData(index);
        //再將新元素放置到下角標index位置
        elementData[index] = element;
        //返回舊值
        return oldValue;
}

    取:

    E get(int index);

public E get(int index) {
        //校驗下角標是否越界
        rangeCheck(index);
        //返回數組中下角標爲index的元素
        return elementData(index);
}

private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

    

    移除:

    E remove(int index);經過下角標移除。

public E remove(int index) {
        //判斷下角標是否越界
        rangeCheck(index);
        //修改次數加一
        modCount++;
        //將數組中下角標爲index的元素賦值給oldValue
        E oldValue = elementData(index);

        //要移動的元素個數
        int numMoved = size - index - 1;
        if (numMoved > 0)
            //若是要移動的元素個數大於0,移動
            // 將elementData數組index+1位置開始拷貝到elementData從index開始的空間 
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        //最後一個元素設爲null,並將size-1
        elementData[--size] = null; // clear to let GC do its work
        返回舊值
        return oldValue;
}

    boolean remove(Object o);移除指定元素

public boolean remove(Object o) {
        if (o == null) {
            //若是要移除的元素爲null
            //循環遍歷數組
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    //若是某個下角標的元素爲null
                    //移除該下角標的元素
                    fastRemove(index);
                    return true;
                }
        } else {
            //循環遍歷數組
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    //若是某個下角標的元素爲o
                    ////移除該下角標的元素
                    fastRemove(index);
                    return true;
                }
        }
        return false;
}

private void fastRemove(int index) {
        //修改次數加一
        modCount++;
        //要移動的元素個數
        int numMoved = size - index - 1;
        if (numMoved > 0)
            // 將elementData數組index+1位置開始拷貝到elementData從index開始的空間 
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work
}
相關文章
相關標籤/搜索