JDK之ArrayList原始碼解讀(三)
目錄
removeAll(Collection<?> c)
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, false);
}
作用:從ArrayList裡刪除存在於Collection c中的所有元素。
先確保Collection c不為null,如果為null,丟擲空指標異常。然後呼叫batchRemove(c, false)
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++) if (c.contains(elementData[r]) == complement) elementData[w++] = elementData[r]; } finally { // 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; }
判斷輸入的Collection當中的資料是否和elementData當中的相等,因為complement為false,即Collection c中的值和ArrayList中的值不相等,就將結果還是放入ArrayList,這樣就過濾掉了相等的部分,相當於刪除操作。finally模組中,中途出現了異常,r為出錯時elementData正在遍歷的位置,w為遍歷後結果儲存的位置。出錯過後,將出錯後沒有遍歷的資料直接新增到結果的後面輸出出來。
class Itr
private class Itr implements Iterator<E> { int cursor; int lastRet = -1; int expectedModCount = modCount; public boolean hasNext() { } @SuppressWarnings("unchecked") public E next() {} public void remove() { } @Override @SuppressWarnings("unchecked") public void forEachRemaining(Consumer<? super E> consumer) {} final void checkForComodification() {} }
作用:實現了Iterator介面,重寫next、hasNext等介面。
cursor表示當前元素的位置,lastRet表示上一個元素的位置。
public boolean hasNext() {
return cursor != size;
}
如果當前元素的位置在ArrayList的末尾,說明迭代器已經遍歷到末尾了,hasNext()返回false。
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
噹噹前元素的位置超出了ArrayList的範圍,丟擲元素不存在的異常;噹噹前元素的位置超出了ArrayList中陣列的範圍,丟擲
ConcurrentModificationException異常。否則返回陣列在cursor位置的值,同時cursor和lastRet都指向陣列的下一位。
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
當lastRet(上一個元素的位置)小於0,丟擲異常;呼叫ArrayList的remove()方法刪除當前元素,同時cursor和lastRet都指向陣列的上一位。
class ListItr
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}
public boolean hasPrevious() {}
public int nextIndex() {}
public int previousIndex() {}
@SuppressWarnings("unchecked")
public E previous() {}
public void set(E e) {}
public void add(E e) {}
}
該類繼承了Itr,並擴充套件了它的功能,添加了是否有上一個元素的判斷、獲取上一個元素的位置、修改某一個位置的值等方法。
public boolean hasPrevious() {
return cursor != 0;
}
作用:判斷迭代器的是否有前一個元素。
如果cursor(當前元素的位置)的值不為0,說明迭代器不是指向第一個元素,存在上一個元素。
public int previousIndex() {
return cursor - 1;
}
作用:獲取迭代器前一個元素的位置。
上一個元素的位置等於當前位置-1。
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
作用:獲取迭代器前一個元素的值。
先獲取上一個元素的位置。當上一個元素的位置小於0,丟擲元素不存在異常;當上一個元素的位置大於陣列長度,也丟擲異常。否則返回陣列在cursor上一個元素位置的值,同時cursor指向陣列的前一位。
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
作用:設定迭代器前一個元素的值。
上一個元素的位置小於0,丟擲狀態不合法異常;呼叫set(int index, E element)方法,設定迭代器前一個元素的值。
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
作用:在迭代器指向的位置新增元素。
sort(Comparator<? super E> c)
@Override
@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c) {
final int expectedModCount = modCount;
Arrays.sort((E[]) elementData, 0, size, c);
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
作用:將ArrayList裡的元素按照Comparator c實現的比較大小規則進行排序。
呼叫Arrays.sort()方法,將數組裡從第一個位置到ArrayList裡最後一個元素的位置,按照Comparator c的規則進行排序。
public static <T> void sort(T[] a, int fromIndex, int toIndex,
Comparator<? super T> c) {
if (c == null) {
sort(a, fromIndex, toIndex);
} else {
rangeCheck(a.length, fromIndex, toIndex);
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, fromIndex, toIndex, c);
else
TimSort.sort(a, fromIndex, toIndex, c, null, 0, 0);
}
}
當Comparator c為null,即排序規則為空時,呼叫sort(a, fromIndex, toIndex)。
public static void sort(Object[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, fromIndex, toIndex);
else
ComparableTimSort.sort(a, fromIndex, toIndex, null, 0, 0);
}
先檢查起始位置與終止位置是否合法
private static void rangeCheck(int arrayLength, int fromIndex, int toIndex) {
if (fromIndex > toIndex) {
throw new IllegalArgumentException(
"fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
}
if (fromIndex < 0) {
throw new ArrayIndexOutOfBoundsException(fromIndex);
}
if (toIndex > arrayLength) {
throw new ArrayIndexOutOfBoundsException(toIndex);
}
}
初始位置不能大於終止位置,不能小於0,終止位置不能大於陣列長度
當用戶請求歸併排序時,呼叫歸併排序方法:
private static void legacyMergeSort(Object[] a,
int fromIndex, int toIndex) {
Object[] aux = copyOfRange(a, fromIndex, toIndex);
mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
}
否則,是用另一種排序方法。
如果之前的Comparator c不為null,則根據Comparator c指定的規則進行排序。