1. 程式人生 > >JAVA集合-03ArrayList原始碼解析和使用例項

JAVA集合-03ArrayList原始碼解析和使用例項

上一章講解了Collection介面下得抽象類和繼承介面,後續深入到具體的實現類,部落格及對應得程式碼可在github上檢視

ArrayList簡介

ArrayList底層實現是陣列,相較於陣列固定大小,ArrayList可以動態的增加;ArrayList繼承AbstractCollection,
實現了List、RandomAccess、Cloneable、Serializable;

  1. ArrayList繼承AbstractCollection,實現了List介面,使得它有集合的基本操作
  2. 實現RandomAccess標記了ArrayList可以隨機訪問元素
  3. 實現Cloneable標記支援克隆
  4. 實現Serializable標記支援序列化

ArrayList不是執行緒安全的,如果在多執行緒條件下使用CopyOnWriteArrayList或者使用Collections.synchronizedList(List list)轉化為執行緒安全的List

建構函式

  1. public ArrayList()
  2. public ArrayList(int initialCapacity)
  3. public ArrayList(Collection<? extends E> c)

ArrayList提供三種建構函式,第一種構建一個初始化容量為0的ArrayList(查閱資料發現說1.6時候會初始化容量為10),
不過在第一次新增元素時候會讓容量變為10;第二種指定初始化容量大小;第三種初始化容量為Collection大小

結構分析

ArrayList

ArrayList包含兩個重要屬性:size和elementData

  1. size表示當前ArrayList包含的元素個數,對於方法ArrayList#size返回的就是它
  2. elementData就是元素存放的位置了

ArrayList原始碼分析(java version:1.8.0_111)

 public boolean add(E e) {
        ensureCapacityInternal(size + 1);//新增元素時候確定容量是否夠用
        elementData[size++] = e;
        return true;
    }
private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//此處就是當容量為0時候新增元素,容量置為10
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }
private void ensureExplicitCapacity(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);//n+n/2
        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);//讓陣列大小變為新的容量大小,這個操作耗時
    }

通過閱讀上面的原始碼可以看出ArrayList每次新增元素時候都會檢查容量是否夠,如果不夠的話,需要擴容;
例如size=10,elementData.length=10,此時底層陣列元素填充滿了 當再次新增元素時候ensureCapacityInternal(size + 1)方法
為ensureCapacityInternal(11)->ensureExplicitCapacity(11)->grow(11)返回16,這也是為什麼說每次擴容都是(size+1)的1.5倍