1. 程式人生 > >java原始碼學習-ArrayList

java原始碼學習-ArrayList

1、 ArrayList類

1.1 繼承 AbstractList
1.2 實現 List<E>, RandomAccess, Cloneable, java.io.Serializable 介面

2、 ArrayList類成員變數

1.1 private static final int DEFAULT_CAPACITY = 10;//預設初始化陣列大小
1.2 private static final Object[] EMPTY_ELEMENTDATA = {};//共享的空陣列物件
1.3 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//共享的預設空陣列物件,與EMPTY_ELEMENTDATA的區別在於在新增元素的時候能否使用DEFAULT_CAPACITY的值進行擴容。
1.4 transient Object[] elementData;//元素儲存的陣列容器
1.5 private int size;//elementData中包含元素的個數

總結:
	成員變數都是私有的,也就是說ArrayList的子類不能直接使用這些屬性值。
	儲存元素的陣列容器用transient修飾,即不參與序列化

3、 ArrayList類構造方法

1.1 public ArrayList(int initialCapacity)
	引數:初始化陣列大小
	初始化邏輯:
	如果initialCapacity大於0,則建立一個initialCapacity大小的elementData陣列
	如果initialCapacity等於0,則elementData為EMPTY_ELEMENTDATA
1.2 public ArrayList()
	初始化邏輯:
	elementData 為 DEFAULTCAPACITY_EMPTY_ELEMENTDATA
1.3  public ArrayList(Collection<? extends E> c) 
	引數:集合
	初始化邏輯:
	如果傳入集合的大小不為0,則將集合轉為陣列,elementData指向該陣列的引用。
	如果傳入的集合的大小為0,則elementData為EMPTY_ELEMENTDATA

4、 ArrayList類核心方法

4.1 保證資料儲存陣列大小
1.1 private void ensureCapacityInternal(int minCapacity);
	引數:希望的最小陣列容量
	邏輯:
		呼叫calculateCapacity方法計算最小陣列容量。傳入ensureExplicitCapacity中。
   		呼叫ensureExplicitCapacity方法,進行擴大儲存資料的陣列大小。
 1.2  private static int calculateCapacity(Object[] elementData, int minCapacity);
 	引數:當前陣列物件elementData,希望的最小陣列容量
 	邏輯:
 		如果當前陣列物件是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,則返回預設的陣列容量大小DEFAULT_CAPACITY和希望的最小陣列容量minCapacity中的最大值。
 		否則,返回希望的最小陣列容量minCapacity。
 1.3 private void ensureExplicitCapacity(int minCapacity)
 	引數:希望的最小陣列容量
	邏輯:
		如果希望的最小輸入容量大小大於當前陣列中元素的數量則擴容。否則不擴容。
 1.4 擴容方法分析
  private void grow(int minCapacity) {//傳入希望的陣列最小容量大小
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);//擴容的計算方法

		//如果擴充後的陣列大小小於了希望的最小容量則使用希望額最小容量大小為當前擴容後的陣列大小
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
         
        //擴容後的陣列大小大於MAX_ARRAY_SIZE=Integer.MAX_VALUE-8,則陣列新的容量為Integer.MAX_VALUE
        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);
    }

5、 總結

1、ArrayList當初始化時不為儲存資料的陣列初始化大小。為一個空陣列。
2、當初始化時傳入了希望最小陣列容量為0或傳入引數集合的個數為0時,新增資料時初始化陣列容量為1。
   當初始化時不傳引數時,新增資料時初始化陣列的容量為預設容量10(即DEFAULT_CAPACITY)。
3、當陣列滿了的時候進行擴容。
4、ArrayList是執行緒不安全的。
5、陣列擴容的方式是 oldCapacity + (oldCapacity >> 1)
6、首次新增元素是使用哪種方式進行初始化陣列大小使用EMPTY_ELEMENTDATA和DEFAULTCAPACITY_EMPTY_ELEMENTDATA來區分。

該文章是在閱讀原始碼的時候總結編寫的,如果有不對的地方請大家多加指正。