標籤:get 接收 表示 copy its initial 添加元素 ast illegal
add操作:
private transient Object[] elementData;private static final int DEFAULT_CAPACITY = 10;public ArrayList() { super(); this.elementData = EMPTY_ELEMENTDATA;}public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity];}public boolean add(E e) { ensureCapacityInternal(size + 1); // 添加之前檢查數組容量,size+1表示接下來要有的容量 elementData[size++] = e;//size初始預設值是0,每添加一個元素自增1,故size表示實際的數組長度 return true;}private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);//如果elementData 為空白集合,即則將傳入的minCapacity和預設值10比較,選出較大的 } ensureExplicitCapacity(minCapacity);}private void ensureExplicitCapacity(int minCapacity) { modCount++; if (minCapacity - elementData.length > 0) //建立對象時如果指定大小則elementData.length為指定的大小,否則elementData.length=0;此處minCapacity 表示需要的數組長度,elementData.length表示擴容後的數組長度,如果是的數組長度 grow(minCapacity);//擴容方法}private void grow(int minCapacity) { int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1);//>> : 右移運算子,num >> 1,相當於num除以2,此處擴容按照原容量大小的一般擴容 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity);//將原有元素拷貝到擴容後的新數組中}總結:elementData 是ArrayList的中間數組,是實際資料的存放數組,size是數組實際的長度,elementData.length都是大於或者等於size的。聲明ArrayList數組時如果指定長度後向數組中添加元素,如果長度超出了ArrayList中間數組的長度(elementData.length)則會增加數組容量,增加原長度的一半容量如果聲明ArrayList數組時沒有指定長度,則預設是空數組,在添加元素的時候,判斷如果當前集合(中間數組)為空白,則將預設長度10賦給數組,即添加第一個元素後的數組容量實際是10
刪除(remove)操作: 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數組 index+1位置上及後面的元素都複製到elementData中,從index位置接收複製元素,接收numMoved個元素 elementData[--size] = null; // clear to let GC do its work 即將最後一個元素置null回收 return oldValue;//返回被移除的元素 }總結:刪除指定位置上的元素是將該數組中該位置以後的元素都往前移動一位,最後一位置null被回收 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; }//此方法和remove類似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 }
總結:移除時先判斷是否是null,如果是要單獨操作,因為null沒有equals方法,通過逐個比較元素來判斷要溢出的元素的位置,再通過類似於remove的方法移除元素
修改/設定(set)操作
set(int index, E element)用指定的元素替代此列表中指定位置上的元素。public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; }總結:直接將指定位置上的元素賦給要賦的值 查詢/擷取(get)操作:
public E get(int index) { rangeCheck(index); return elementData(index); }總結:直接返回指定位置上的數組元素
ArrayList源碼解析