package java.util; public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8683452581122892189L; /** * 默認的長度 */ private static final int DEFAULT_CAPACITY = 10; /** * 在new ArrayList的這個無參構造方法中會給Object []一個空的對象 */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * 這個就是ArrayList維護的數組 */ private transient Object[] elementData; /** *集合的大小 */ private int size; /** *能夠指定長度 */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } /** * 默認無參構造方法,裏面會初始化這個維護的數組 */ public ArrayList() { super(); this.elementData = EMPTY_ELEMENTDATA; } /** * 能夠傳進來一個集合,這裏轉成數組以後傳給elementData * 而後判斷是不是object[]類型,若不是則複製一個給elementData */ public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) {//空數組 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { modCount++; // 判斷總容量大小+1是否比原數組長度大,即最新的元素可否加進去,加不進去則擴容 if (minCapacity - elementData.length > 0) grow(minCapacity);//擴容 } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1);//容量增長爲原來的1.5 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);//拷貝一個新的數組指向原數組 } public int size() { return size; } public boolean isEmpty() { return size == 0; } /****/ public E get(int index) { rangeCheck(index);//檢查下標 return elementData(index);//根據下標拿值 } /** * */ public E set(int index, E element) { rangeCheck(index);//檢查下標是否越界 E oldValue = elementData(index); elementData[index] = element;//將新值替換 return oldValue; } /** * 相似 add(int index, E element)方法,不在贅述 */ public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } /** * 添加到指定位置 */ public void add(int index, E element) { rangeCheckForAdd(index);//檢查下標是否越界 ensureCapacityInternal(size + 1); // 會在原來長度基礎上+1而後判斷當前數組是否爲空,若爲空判斷長度是否大於默認值的10個長度,返回最大值,若以前的長度小於此長度(原長已經知足不了,須要擴容),在此基礎上擴展元素的長度爲以前+以前的一半,length>>1 System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } /** * 相對於根據對象刪除效率高些,由於這裏是直接根據下標進行刪除 ,少了迭代 */ public E remove(int index) { rangeCheck(index);//檢查下標是否越界 modCount++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) //這裏是將elementData複製到本身自己,從須要刪除的位置開始+1,複製的長度爲總長度-刪除的位置-1也就是將刪除位置開始日後的元素所有前移,由於自己長度多了最後一個元素,好比[1,2,3,4],刪除index=1的元素這裏把3,4插入到以前的元素位置變成[1,3,4,4]多了最後一個元素,後面會把他清除 System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; //這裏清除最後一個多於的元素 return oldValue; } /** * 根據對象刪除,遍歷數組,找到第一個符合的元素進行刪除,刪除步驟請看fastRemove()方法 */ 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) //這裏是將elementData複製到本身自己,從須要刪除的位置開始+1,複製的長度爲總長度-刪除的位置-1也就是將刪除位置開始日後的元素所有前移,由於自己長度多了最後一個元素,好比[1,2,3,4],刪除index=1的元素這裏把3,4插入到以前的元素位置變成[1,3,4,4]多了最後一個元素,後面會把他清除 System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // 清除最後一個多餘的元素 } /** *遍歷數組,將每個元素的值都置爲null */ public void clear() { modCount++; // clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; } /** 看上面幾個方法,不在贅述 */ public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; } /** 看上面幾個方法,不在贅述 */ public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; } }