java中ArrayList動態增加原理及源碼分析

  ArrayList分析數組

  

  1.ArrayList底層數據結構是一個動態數組。安全

   源碼中的定義爲:transient Object[] elementData; 還定義了數組的大小private int size;數據結構

   集合的三個構造方法:  多線程

   第一個: 帶有集合初始化大小的構造方法this

 

 

  

 1     public ArrayList(int initialCapacity) {  2         if (initialCapacity > 0) {  3             this.elementData = new Object[initialCapacity];  4         } else if (initialCapacity == 0) {  5             this.elementData = EMPTY_ELEMENTDATA;  6         } else {  7             throw new IllegalArgumentException("Illegal Capacity: "+
 8  initialCapacity);  9  } 10     }

   第二個:空構造方法spa

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

   第三個:經過集合的構造方法線程

public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA; } }

   ArrayList集合底層爲動態數組,不少方法都是基於數組的底層下實現的,而這裏實現動態數組的擴容1.5倍是這個集合動態構建的方法,直接上jdk源碼code

//簡單分析ensureCapacity:確保容量,經過minExpand來記錄當前的容量,經過傳入minCapacity來判斷是否須要擴展容量 
public void ensureCapacity(int minCapacity) { int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) // any size if not default element table ? 0 // larger than default for default empty table. It's already // supposed to be at default size. : DEFAULT_CAPACITY;
if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } }
//直接調用ensureExplicitCapacity方法
private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
//擴容處理,經過if進一步確認是否真的須要擴容
private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }
//這個變量,是VMs存儲了些頭信息在裏面,源碼註釋是這麼說具體也不是特別瞭解爲何要少8.
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//真正的動態增加,newCapacity = oldCapacity + (oldCapacity >> 1);實現增加1.5倍,位運算經過右移一位。ps:位運算應該是各類運算中速度最快的了
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); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }

   剩下的那些ArrayList的方法其實和普通的操做數組的方法都是同樣的,你們直接看源碼就能夠很簡單的瞭解到了,這裏就不重複了╮(╯_╰)╭blog

    這裏仍是要提一下的,ArrayList是非線程安全,因此多線程同時修改ArrayList集合的時候,及其有可能發生錯誤,若是要多線程環境實現,就使用vector集合ci

相關文章
相關標籤/搜索