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