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);
}