簡介數組
ArrayList是Java集合經常使用的數據結構之一,繼承自AbstractList,實現了List,RandomAccess、Cloneable、Serializable等一系列接口,支持快速訪問,複製和序列化。底層是基於數組實現容量大小動態變化,容許null值存在。數據結構
部分源碼分析dom
ArrayList的底層是由數組實現函數
默認size的初始大小爲10:源碼分析
ArrayList定義了兩個類常量數組:EMPTY_ELEMENTDATA(EE)和DEFAULTCAPACITY_EMPTY_ELEMENTDATA(DEE)性能
註釋:EE,用於ArrayList空實例的共享空數組實例優化
DEE,用於默認大小空實例的共享空數組實例,將EE和DEE區分開,以便在添加第一個元素時知道要增長多少spa
三個構造函數,包括一個無參構造和兩個有參構造:3d
注:無參構造建立的實例是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,有參構造建立的實例是EMPTY_ELEMENTDATA對象
而後是add( )方法:
當第一次調用add(E e)方法時,判斷是否是無參構造方法建立的對象,若是是,則將DEFAULT_CAPACITY做爲ArrayLiat的容量,此時minCapacity = 1
還有其餘add方法例如:
addAll( Collection<? extends E> c )
add( int index, E element )
等等....這些方法中都包含ensureCapacitylnternal( int Capacity )方法,確保無參構造在建立實例並添加第一個元素時,最小的容量是默認大小10。
而有參構造建立空實例後,在add( E e )方法添加元素擴容狀況是這樣的:
新容量爲舊容量的1.5倍
在Java7中,ArrayList的構造方法只有EMPTY_ELEMENTDATA即EE, 而Java8中DEE代替了EE,可是原來的EE還存在,只是做用改變了:
當容量爲0時,會建立一個空數組,賦值給elementData,當一個應用中有不少這樣的ArrayList空實例時,就會有不少空數組,這樣使用EMPTY_ELEMENTDATA就是爲了優化性能,全部的ArrayList空實例都指向同一個數組。而DEE(DEFAULTCAPACITY_EMPTY_ELEMENTDATA)就是爲了保證無參構造方法常見的實例在添加第一個元素時,最小的容量是默認的10.
ArrayList的擴容
以無參構造爲例:
首先無參構造初以默認大小來始化內部數組
而後是擴容,使用add( )方法
ensureCapacityInternal方法中的size表明執行添加前的元素個數,經過現有的元素個數數組的容量進行對比,若須要擴容則擴容。
ensureCapacityInternal(size + 1)就是將要添加的額元素放入數組中
擴容條件:若數組的長度eleentData的長度小於作小須要的容量minCapacity,就須要擴容
擴容邏輯:
注:
1. >>位運算,右移一位表明oldCapacity / 2,位運算效率更高
2. JDK7後增長對元素個數的最大個數判斷,MAX_ARRAY_SIZE爲int最大值減去8
3. 複製元素方法擴容。使用延遲分配對象數組空間,當數組加滿數組容量後纔會按照1.5倍擴容。
ArrayList的remove( int index )方法
當咱們調用remove( int index )時,首先調用rangrCheck( ) 方法檢查index是否合法,再判斷要刪除的元素是否位於數組的最後一個位置。
當index是最後一個,則直接將數組的最後一個位置置空,即size-1便可;
當index不是最後一個,調用System.arraycopy( )方法複製數組,將從index+1開始,全部元素都往前挪一個位置,再將數組最後一個位置置空。