1、ArrayList 屬性數組
// 默認容量 private static final int DEFAULT_CAPACITY = 10; // 一個空對象 private static final Object[] EMPTY_ELEMENTDATA = {}; // 一個空對象,無參默認建立 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 數據對象存放的地方,不參與序列化 transient Object[] elementData;// 1.transient 不參與序列化,思考:這個變量爲何不須要序列化?是能夠經過計算獲得?顯然不是,那爲何這麼設計呢? // 實際的長度 private int size; // 數組最大長度 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
2、構造函數函數
1.無參構造函數this
public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
也就是說,此時的ArrayList 爲空對象,建立出來的size爲0spa
2.帶int類型的構造參數.net
public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
3.帶Collection類型的構造參數設計
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底層就是Array數組code
3、方法對象
1.add()方法blog
1.1 add(E e)ci
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! // 1.1.1 ensureCapacityInternal 確認size+1以後不超過容量 elementData[size++] = e;// 將elementData[size] = e; size自增 return true; }
1.1.1 ensureCapacityInternal
private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//若是空數組,則返回(默認容量和數組+1以後的容量)的最大值,也就是這裏會返回默認容量10 return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; } private void ensureExplicitCapacity(int minCapacity) { modCount++; // abstractList protected transient int modCount = 0; 記錄變動次數 // 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); 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; }
第一次add時,elementData 長度變爲10,而後一直能夠添加,若添加到11個的時候,執行grow()方法, 將當前數組的長度變爲原來容量的1.5倍,繼續循環添加,
1.2 add(int index, E element)
public void add(int index, E element) { rangeCheckForAdd(index); //參數判斷,若超出數組長度或者小於0則拋出IndexOutOfBoundsException ensureCapacityInternal(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index);// index 以後的元素都日後移動1,包括index的元素 elementData[index] = element;// 而後將index的元素賦值爲插入的元素 size++; } private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
2.remove
2.1 remove(int index)
public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; }
此方法不縮減數組容量
將最後一個元素置爲null,以便垃圾回收
返回被移除的元素
2.2 remove(Object o)
public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; } private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }
若移除,返回true;若沒有找到,返回false
參考文檔:
https://blog.csdn.net/fighterandknight/article/details/61240861