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,size-1)複製到(index,size-1) elementData[--size] = null; // size-1,最後一個元素置爲null return oldValue; }
下標檢查,若是大於數組的size,拋出異常數組
private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
2.1傳進來null,刪除第一個值爲null的值(注意此時加入了兩個null值)ui
此時執行了一句list.remove(null);只刪除了在物理位置上比較靠前的null,第二次刪除纔會刪除第二個nullthis
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; }
此方法執行的就是上面"返回刪除元素"方法中的內容spa
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; }
public boolean retainAll(Collection<?> c) { Objects.requireNonNull(c); // 檢查,若是此對象爲空,拋出空指針異常 return batchRemove(c, true); }
private boolean batchRemove(Collection<?> c, boolean complement) { final Object[] elementData = this.elementData; int r = 0, w = 0; boolean modified = false; try { for (; r < size; r++) //若是傳入的集合c,包含當前所遍歷的數組的元素,從新整理一下list中的元素 if (c.contains(elementData[r]) == complement) elementData[w++] = elementData[r]; } finally { // 拋出異常後的處理(下面爲JDK中的描述) // Preserve behavioral compatibility with AbstractCollection, // even if c.contains() throws. if (r != size) { System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } if (w != size) { // clear to let GC do its work for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; }