2.5.7 indexOf(Object o, Object[] elements, int index, int fence)
/**
* 查詢元素在指定數組中在index索引到fence索引之間是否存在,如果存在,則傳回索引,不存在,傳回-1
* 元素可以為null
*/
private static int indexOf(Object o, Object[] elements,
int index, int fence) {
if (o == null) {
for (int i = index; i < fence; i++)
if (elements[i] == null)
return i;
} else {
for (int i = index; i < fence; i++)
if (o.equals(elements[i]))
return i;
}
return -1;
}
2.5.8 lastIndexOf(Object o, Object[] elements, int index)
/**
* 判斷對象O在資料elements上index索引前最後一次出現的位置,如果有,則傳回索引,否則傳回-1
*/
private static int lastIndexOf(Object o, Object[] elements, int index) {
if (o == null) {
for (int i = index; i >= 0; i--)
if (elements[i] == null)
return i;
} else {
for (int i = index; i >= 0; i--)
if (o.equals(elements[i]))
return i;
}
return -1;
}
/**
* 查詢對象O在目前數組中的索引,如果有傳回索引,沒有傳回-1
*/
public int indexOf(Object o) {
Object[] elements = getArray();
return indexOf(o, elements, 0, elements.length);
}
2.5.11 indexOf(E e, int index)
/**
* 查詢元素E在目前數組中從索引index處開始首次出現的位置, 如果有,傳回索引,沒有,傳回-1
*/
public int indexOf(E e, int index) {
Object[] elements = getArray();
return indexOf(e, elements, index, elements.length);
}
2.5.12 lastIndexOf(Object o)
/**
* 查詢對象O在目前數組中最後出現的位置索引,有傳回,沒有傳回-1
*/
public int lastIndexOf(Object o) {
Object[] elements = getArray();
return lastIndexOf(o, elements, elements.length - 1);
}
2.5.13 lastIndexOf(E e, int index)
/**
* 擷取元素e在目前數組中指定index索引之前最後出現的位置索引,如果有,傳回,否則傳回-1
*/
public int lastIndexOf(E e, int index) {
Object[] elements = getArray();
return lastIndexOf(e, elements, index);
}
2.5.14 clone()
/**
* 調用Object的clone()方法進行淺拷貝, 内部元素并沒有拷貝
* 然後調用resetLock()方法在指定的lock偏移量位置重新new了一個ReentrantLock對象,重置鎖
*/
public Object clone() {
try {
@SuppressWarnings("unchecked")
CopyOnWriteArrayList<E> clone = (CopyOnWriteArrayList<E>) super.clone();
clone.resetLock();
return clone;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
/**
* 如果元素在快照中不存在,則添加,否則,傳回false
*/
private boolean addIfAbsent(E e, Object[] snapshot) {
// 加鎖
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 備份數組,擷取長度
Object[] current = getArray();
int len = current.length;
// 如果傳遞的數組和内部數組快照不同
if (snapshot != current) {
// Optimize for lost race to another addXXX operation
// 擷取傳遞數組和内部維護數組的長度最小值,友善快速判斷
int common = Math.min(snapshot.length, len);
// 周遊,快照中如果元素在0~common索引之間存在則傳回false
for (int i = 0; i < common; i++)
if (current[i] != snapshot[i] && eq(e, current[i]))
return false;
// 如果快照中元素在common,len之間存在,也傳回false
if (indexOf(e, current, common, len) >= 0)
return false;
}
// 建立新長度的數組,長度比之前大1,并将新增元素添加
Object[] newElements = Arrays.copyOf(current, len + 1);
newElements[len] = e;
// 寫回内部維護數組
setArray(newElements);
return true;
} finally {
// 解鎖
lock.unlock();
}
}
2.2.29 containsAll(Collection<?> c)
/**
* 判斷内部維護的數組是否包含傳入集合的所有元素
*/
public boolean containsAll(Collection<?> c) {
// 備份數組并記錄長度
Object[] elements = getArray();
int len = elements.length;
// 周遊傳遞過來的集合中的元素,檢視是否在快照中存在,有一個不存在就傳回false
for (Object e : c) {
if (indexOf(e, elements, 0, len) < 0)
return false;
}
// 如果元素都存在則傳回true
return true;
}
2.2.30 removeAll(Collection<?> c)
/**
* 删除内部數組中在傳遞數組中的所有元素
*/
public boolean removeAll(Collection<?> c) {
// 參數校驗
if (c == null) throw new NullPointerException();
// 加鎖
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 備份數組快照并記錄長度
Object[] elements = getArray();
int len = elements.length;
if (len != 0) {
// temp array holds those elements we know we want to keep
int newlen = 0;
// 建立臨時數組,長度為快照的長度
Object[] temp = new Object[len];
// 周遊快照,如果元素在目标數組中不存在,則将元素放到新數組中
for (int i = 0; i < len; ++i) {
Object element = elements[i];
if (!c.contains(element))
temp[newlen++] = element;
}
// 重置新數組的長度,并寫回到内部維護的數組
if (newlen != len) {
setArray(Arrays.copyOf(temp, newlen));
return true;
}
}
return false;
} finally {
// 解鎖
lock.unlock();
}
}
2.2.31 retainAll(Collection<?> c)
/**
* 擷取内部數組和目标數組的交集,并寫回到内部數組
*/
public boolean retainAll(Collection<?> c) {
// 空指針校驗
if (c == null) throw new NullPointerException();
// 加鎖
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 備份數組和擷取長度
Object[] elements = getArray();
int len = elements.length;
if (len != 0) {
// 建立一個新數組用來儲存希望保留的元素
int newlen = 0;
Object[] temp = new Object[len];
// 周遊備份數組,如果元素同時在備份數組和目标數組中存在,則存儲到新數組中
for (int i = 0; i < len; ++i) {
Object element = elements[i];
if (c.contains(element))
temp[newlen++] = element;
}
// 如果倆個長度不相等,則将新數組寫回 如果倆個數組相同,則不需要寫回
if (newlen != len) {
setArray(Arrays.copyOf(temp, newlen));
return true;
}
}
return false;
} finally {
// 解鎖
lock.unlock();
}
}
2.2.32 addAllAbsent(Collection<? extends E> c)
/**
* 将目标集合中不存在的元素添加的内部維護的數組中 取并集
*/
public int addAllAbsent(Collection<? extends E> c) {
// 将目标集合轉換為數組并校驗長度
Object[] cs = c.toArray();
if (cs.length == 0)
return 0;
// 加獨占鎖
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 備份内部數組并擷取長度
Object[] elements = getArray();
int len = elements.length;
int added = 0;
// uniquify and compact elements in cs
// 周遊目标數組
for (int i = 0; i < cs.length; ++i) {
Object e = cs[i];
// 如果目标數組中的對象在備份的内部數組中不存在并且在目标數組之前沒有出現過
if (indexOf(e, elements, 0, len) < 0 &&
indexOf(e, cs, 0, added) < 0)
cs[added++] = e;
}
// added大于0說明存在并集元素
if (added > 0) {
// 建立新數組,将原備份數組拷貝進去,并将長度修改為并集的長度
Object[] newElements = Arrays.copyOf(elements, len + added);
// 将目标數組從0角标開始拷貝added個元素到新數組的len角标後面
System.arraycopy(cs, 0, newElements, len, added);
// 寫回
setArray(newElements);
}
// 傳回添加的元素個數
return added;
} finally {
// 解鎖
lock.unlock();
}
}
2.2.35 addAll(int index, Collection<? extends E> c)
/**
* 将目标數組插入到新數組中
*/
public boolean addAll(int index, Collection<? extends E> c) {
// 将目标參數轉換為數組
Object[] cs = c.toArray();
// 加獨占鎖
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 備份内部維護數組并擷取長度
Object[] elements = getArray();
int len = elements.length;
// 校驗參數
if (index > len || index < 0)
throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+len);
if (cs.length == 0)
return false;
// 根據開始添加元素的索引計算需要移動元素個數
int numMoved = len - index;
// 建立新數組
Object[] newElements;
// 如果是數組末尾,則隻是備份舊數組到新數組中,擴充長度
if (numMoved == 0)
newElements = Arrays.copyOf(elements, len + cs.length);
else {
// 建立新數組,建立新長度
newElements = new Object[len + cs.length];
// 将舊數組中index索引之前的元素拷貝到新數組中
System.arraycopy(elements, 0, newElements, 0, index);
// 将舊數組中index索引之後的元素拷貝到新數組中插入新元素集合之後的角标之後
System.arraycopy(elements, index, newElements, index + cs.length, numMoved);
}
// 将目标數組插入到新數組中
System.arraycopy(cs, 0, newElements, index, cs.length);
// 寫回内部數組
setArray(newElements);
return true;
} finally {
// 解鎖
lock.unlock();
}
}
2.2.36 forEach(Consumer<? super E> action)
/**
* jdk8的lambda方式forEach周遊
*/
public void forEach(Consumer<? super E> action) {
// 校驗參數
if (action == null) throw new NullPointerException();
// 備份數組并擷取長度
Object[] elements = getArray();
int len = elements.length;
// 調用1.8的函數式接口擷取元素
for (int i = 0; i < len; ++i) {
@SuppressWarnings("unchecked") E e = (E) elements[i];
action.accept(e);
}
}
2.2.37 removeIf(Predicate<? super E> filter) TODO jdk8
/**
*
*/
public boolean removeIf(Predicate<? super E> filter) {
// 參數校驗
if (filter == null) throw new NullPointerException();
// 加獨占鎖
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 備份數組并擷取長度
Object[] elements = getArray();
int len = elements.length;
if (len != 0) {
int newlen = 0;
Object[] temp = new Object[len];
for (int i = 0; i < len; ++i) {
@SuppressWarnings("unchecked") E e = (E) elements[i];
if (!filter.test(e))
temp[newlen++] = e;
}
if (newlen != len) {
setArray(Arrays.copyOf(temp, newlen));
return true;
}
}
return false;
} finally {
lock.unlock();
}
}
2.2.38 replaceAll(UnaryOperator<E> operator) TODO jdk8
public void replaceAll(UnaryOperator<E> operator) {
if (operator == null) throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len);
for (int i = 0; i < len; ++i) {
@SuppressWarnings("unchecked") E e = (E) elements[i];
newElements[i] = operator.apply(e);
}
setArray(newElements);
} finally {
lock.unlock();
}
}
2.2.39 sort(Comparator<? super E> c)
/**
* 使用指定的排序器進行排序
*/
public void sort(Comparator<? super E> c) {
// 加獨占鎖
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 備份數組
Object[] elements = getArray();
// 建立新數組,元素和備份數組一樣
Object[] newElements = Arrays.copyOf(elements, elements.length);
// 調用Arrays的sort方法進行排序
@SuppressWarnings("unchecked") E[] es = (E[])newElements;
Arrays.sort(es, c);
// 寫回
setArray(newElements);
} finally {
// 解鎖
lock.unlock();
}
}
2.2.40 writeObject(java.io.ObjectOutputStream s)
/**
* 将數組寫入到指定的輸出流中
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
// 寫數組對象資料
s.defaultWriteObject();
// 備份數組,并将數組的長度寫到流中
Object[] elements = getArray();
s.writeInt(elements.length);
// 将數組元素以合适的順序寫到輸出流中
for (Object element : elements)
s.writeObject(element);
}
2.2.41 readObject(java.io.ObjectInputStream s)
/**
* 從輸入流中擷取數組并寫回
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// 讀對象
s.defaultReadObject();
// 擷取新的獨占鎖
resetLock();
// 從流中擷取對象數組的長度
int len = s.readInt();
// 校驗長度
SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, len);
// 建立新數組
Object[] elements = new Object[len];
// 從流中擷取對象數組内部的元素
for (int i = 0; i < len; i++)
elements[i] = s.readObject();
// 寫回
setArray(elements);
}
2.2.42 toString()
/**
* 重寫toString方法,内部調用Arrays的toString方法
*/
public String toString() {
return Arrays.toString(getArray());
}
/**
* Arrays的toString(Arr[])方法,内部采用StringBuilder方法進行拼接
*/
public static String toString(Object[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(String.valueOf(a[i]));
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
2.2.43 equals(Object o)
/**
* 重寫equals方法
*/
public boolean equals(Object o) {
// 如果位址相等,則傳回true
if (o == this)
return true;
// 如果對象不是List類型,則傳回false
if (!(o instanceof List))
return false;
// 強轉為List類型并擷取疊代器
List<?> list = (List<?>)(o);
Iterator<?> it = list.iterator();
// 備份内部維護數組并擷取長度
Object[] elements = getArray();
int len = elements.length;
// 周遊目标數組,周遊長度為備份數組的長度
for (int i = 0; i < len; ++i)
// 如果二者元素不同則傳回false
if (!it.hasNext() || !eq(elements[i], it.next()))
return false;
// 如果目标數組比備份數組長度長,則傳回false
if (it.hasNext())
return false;
return true;
}
2.2.44 hashCode()
/**
* 重寫hashCode方法
*/
public int hashCode() {
// 初始哈希值為1
int hashCode = 1;
// 備份數組并擷取長度
Object[] elements = getArray();
int len = elements.length;
// 周遊元素,根據每一個元素計算一次哈希值
for (int i = 0; i < len; ++i) {
Object obj = elements[i];
// 重新計算哈希值
hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
}
// 傳回新的哈希值
return hashCode;
}
2.2.45 iterator()
/**
* 擷取疊代器,傳回内部自定義類COWIterator的疊代器
*/
public Iterator<E> iterator() {
return new COWIterator<E>(getArray(), 0);
}
2.2.46 listIterator()
/**
* 擷取疊代器,傳回内部自定義類COWIterator的疊代器
*/
public ListIterator<E> listIterator() {
return new COWIterator<E>(getArray(), 0);
}
2.2.47 listIterator(int index)
/**
* 擷取疊代器,傳回内部自定義的COWIterator疊代器,疊代的集合從index索引開始
*/
public ListIterator<E> listIterator(int index) {
// 備份數組并擷取長度
Object[] elements = getArray();
int len = elements.length;
// 校驗參數
if (index < 0 || index > len)
throw new IndexOutOfBoundsException("Index: "+index);
// 傳回自定義的疊代器
return new COWIterator<E>(elements, index);
}