1. 类的定义
public class CopyOnWriteArrayList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
复制代码
从类的定义中可以看出
- CopyOnWriteArrayList是一个泛型类
- CopyOnWriteArrayList实现了List接口,表示它是一个集合
- CopyOnWriteArrayList 实现了RandomAccess接口,表示支持随机访问
- CopyOnWriteArrayList实现了Cloneable接口,表示支持克隆
- CopyOnWriteArrayList实现了java.io.Serializable接口,表示支持序列化
2. 字段属性
//序列化版本号
private static final long serialVersionUID = 8673264195747942595L;
//锁,访问数组的时候使用
final transient ReentrantLock lock = new ReentrantLock();
//Object数组,存储元素的容器
private transient volatile Object[] array;
复制代码
从字段属性可以看出
- CopyOnWriteArrayList的底层是一个Object数组
- CopyOnWriteArrayList通过ReentrantLock来实现同步
3. 构造方法
//默认空构造方法
public CopyOnWriteArrayList() {
//创建一个空集合
setArray(new Object[0]);
}
//传入一个集合对象的构造方法
public CopyOnWriteArrayList(Collection<? extends E> c) {
Object[] elements;
if (c.getClass() == CopyOnWriteArrayList.class)
//如果传入的是一个CopyOnWriteArrayList集合对象
//直接获取array数组
elements = ((CopyOnWriteArrayList<?>)c).getArray();
else {
//如果是其他的集合对象
//先获取集合对象的元素,并转换为数组
elements = c.toArray();
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elements.getClass() != Object[].class)
//有可能c的元素不是Object对象
//使用Arrays.copyOf来做强转Object操作
elements = Arrays.copyOf(elements, elements.length, Object[].class);
}
//把上面获取到的Object数组赋值给当前对象
setArray(elements);
}
//传入一个数组对象
public CopyOnWriteArrayList(E[] toCopyIn) {
//使用Arrays.copyOf来做强转Object操作,再赋值给当前对象
setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
}
复制代码
从构造方法可以看出
- CopyOnWriteArrayList默认是一个长度为0的数组
- CopyOnWriteArrayList可以接收一个集合对象来初始化
- CopyOnWriteArrayList可以接收一个数组对象来初始化
4. 方法
getArray 方法
//获取array数组
final Object[] getArray() {
return array;
}
复制代码
setArray 方法
//设置array数组
final void setArray(Object[] a) {
array = a;
}
复制代码
size 方法
//获取列表的长度
public int size() {
//返回数组的长度
return getArray().length;
}
复制代码
isEmpty 方法
//列表是否为空
public boolean isEmpty() {
//数组长度是否为0
return size() == 0;
}
复制代码
eq 方法
//判断两个对象是否相等
private static boolean eq(Object o1, Object o2) {
//如果一个为null,判断另一个是否为null
//否则使用equals来比较
return (o1 == null) ? o2 == null : o1.equals(o2);
}
复制代码
indexOf 方法
//获取指定区间指定元素的下标,如果元素重复只返回第一个下标
private static int indexOf(Object o, Object[] elements,
int index, int fence) {
if (o == null) {
//如果对象为null,使用for循环遍历并使用==判断
for (int i = index; i < fence; i++)
if (elements[i] == null)
return i;
} else {
//如果对象不为null,使用for循环遍历并使用equals判断
for (int i = index; i < fence; i++)
if (o.equals(elements[i]))
return i;
}
//没找到返回-1
return -1;
}
//获取指定元素的下标
public int indexOf(Object o) {
Object[] elements = getArray();
//调用上面的方法查找
return indexOf(o, elements, 0, elements.length);
}
//从指定开始位置查找指定元素的下标
public int indexOf(E e, int index) {
Object[] elements = getArray();
//调用第一个方法
return indexOf(e, elements, index, elements.length);
}
复制代码
lastIndexOf 方法
//获取指定结束位置指定元素的最后一个下标,如果元素重复只返回最后一个下标
private static int lastIndexOf(Object o, Object[] elements, int index) {
if (o == null) {
//如果对象为null,使用for循环遍历并使用==判断
//从指定位置index往前遍历
for (int i = index; i >= 0; i--)
if (elements[i] == null)
return i;
} else {
//如果对象不为null,使用for循环遍历并使用equals判断
//从指定位置index往前遍历
for (int i = index; i >= 0; i--)
if (o.equals(elements[i]))
return i;
}
//没找到返回-1
return -1;
}
//获取指定元素的最后一个下标,如果元素重复只返回最后一个下标
public int lastIndexOf(Object o) {
Object[] elements = getArray();
//调用上面的方法
return lastIndexOf(o, elements, elements.length - 1);
}
//从指定结束位置查找指定元素的最后一个下标,如果元素重复只返回最后一个下标
public int lastIndexOf(E e, int index) {
Object[] elements = getArray();
return lastIndexOf(e, elements, index);
}
复制代码
contains 方法
//集合中是否包含指定元素
public boolean contains(Object o) {
//获取数组副本
Object[] elements = getArray();
//调用indexOf方法查找指定元素
return indexOf(o, elements, 0, elements.length) >= 0;
}
复制代码
clone 方法
public Object clone() {
try {
@SuppressWarnings("unchecked")
//调用父类的clone方法,浅拷贝
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();
}
}
复制代码
toArray 方法
//转化为数组
public Object[] toArray() {
Object[] elements = getArray();
//通过Arrays.copyOf来拷贝数组
return Arrays.copyOf(elements, elements.length);
}
//把集合元素复制到指定数组中
public <T> T[] toArray(T a[]) {
//获取数组的副本
Object[] elements = getArray();
//获取数组长度
int len = elements.length;
if (a.length < len)
//如果目标数组的长度小于当前数组的长度
//使用Arrays.copyOf进行拷贝
return (T[]) Arrays.copyOf(elements, len, a.getClass());
else {
//如果目标数组的长度大于等于当前数组长度
//直接使用System.arraycopy来进行拷贝,拷贝长度为当前数组长度
System.arraycopy(elements, 0, a, 0, len);
if (a.length > len)
//把最后一个置为null
a[len] = null;
//返回目标数组
return a;
}
}
复制代码
get 方法
//获取指定数组的指定下标的元素
private E get(Object[] a, int index) {
return (E) a[index];
}
//获取指定下标的元素
public E get(int index) {
//调用上面的方法
return get(getArray(), index);
}
复制代码
set 方法
//把指定元素设置到指定位置
public E set(int index, E element) {
//上锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
//获取数组副本
Object[] elements = getArray();
//获取指定位置的旧值
E oldValue = get(elements, index);
if (oldValue != element) {
//如果旧值不等于新值
//获取数组长度
int len = elements.length;
//拷贝一份新的数组
Object[] newElements = Arrays.copyOf(elements, len);
//在指定位置设置新值
newElements[index] = element;
//设置新的数组
setArray(newElements);
} else {
// Not quite a no-op; ensures volatile write semantics
//新值等于旧值,没有任何操作,确保语义上的volatile写
setArray(elements);
}
//返回旧值
return oldValue;
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
add 方法
//添加指定元素
public boolean add(E e) {
//上锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
//获取数组副本
Object[] elements = getArray();
//获取数组长度
int len = elements.length;
//复制数组并把长度扩容为数组len+1
Object[] newElements = Arrays.copyOf(elements, len + 1);
//设置指定元素
newElements[len] = e;
//设置新的数组
setArray(newElements);
return true;
} finally {
//释放锁资源
lock.unlock();
}
}
//添加指定元素到指定位置
public void add(int index, E element) {
//上锁
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);
Object[] newElements;
//计算需要移动的数量,从插入位置,后面的元素统一向后移动一位
int numMoved = len - index;
if (numMoved == 0)
//如果移动位置为0,表示末尾插入
//跟上面的方法一样了
//复制数组并把长度扩容为数组len+1
newElements = Arrays.copyOf(elements, len + 1);
else {
//插入的位置在中间的情况
//创建新的容量为len+1的数组
newElements = new Object[len + 1];
//拷贝0到index的元素
System.arraycopy(elements, 0, newElements, 0, index);
//拷贝index+1到末尾的元素
System.arraycopy(elements, index, newElements, index + 1,
numMoved);
}
//设置index的元素为新元素
newElements[index] = element;
//设置新的数组
setArray(newElements);
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
remove 方法
//移除指定位置的元素并返回指定位置的值
public E remove(int index) {
//上锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
//获取数组的副本
Object[] elements = getArray();
//获取数组的长度
int len = elements.length;
//获取指定元素的旧值
E oldValue = get(elements, index);
//计算移动的数量,移除元素相当于把移除位置后所有的元素向前移动一位
int numMoved = len - index - 1;
if (numMoved == 0)
//如果移动数量为0, 表示移除末尾元素
//把数组元素的0到len-1的元素拷贝就行
setArray(Arrays.copyOf(elements, len - 1));
else {
//移除的元素不在末尾
//创建len-1的新数组
Object[] newElements = new Object[len - 1];
//拷贝0到inde的元素
System.arraycopy(elements, 0, newElements, 0, index);
//拷贝index+1到末尾的元素
System.arraycopy(elements, index + 1, newElements, index,
numMoved);
//设置新数组
setArray(newElements);
}
//返回旧值
return oldValue;
} finally {
//释放锁资源
lock.unlock();
}
}
//移除指定对象
public boolean remove(Object o) {
//获取数组对象
Object[] snapshot = getArray();
//获取指定对象的下标
int index = indexOf(o, snapshot, 0, snapshot.length);
//如果不存在返回false
//存在使用下面的方法移除对应位置的元素
return (index < 0) ? false : remove(o, snapshot, index);
}
//从指定数组中移除指定位置的元素
private boolean remove(Object o, Object[] snapshot, int index) {
//上锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
//获取数组副本
Object[] current = getArray();
//获取数组的长度
int len = current.length;
//如果数组被修改,快照不等于当前数组
//这里有一个goto
if (snapshot != current) findIndex: {
//获取指定位置和长度的最小值
int prefix = Math.min(index, len);
//for循环,从0到index遍历
for (int i = 0; i < prefix; i++) {
if (current[i] != snapshot[i] && eq(o, current[i])) {
//i的位置被修改,并且i的位置元素为o
//既然i的元素也是o,就算被修改了,移除i的元素也一样,反正只要移除o就行
//大概就是不断调整index的位置,因为可能被修改,而且可能存在多个o对象
//把index置为i,继续goto
index = i;
break findIndex;
}
}
if (index >= len)
//如果下标大于数组长度,直接返回false
return false;
if (current[index] == o)
//如果当前元素等于o,goto findIndex
break findIndex;
//获取index到len区间,o的下标
index = indexOf(o, current, index, len);
if (index < 0)
//如果o不存在,直接返回false
return false;
}
//创建新的数组,长度为len-1
Object[] newElements = new Object[len - 1];
//拷贝0到index的元素
System.arraycopy(current, 0, newElements, 0, index);
//拷贝index+1到末尾的元素
System.arraycopy(current, index + 1,
newElements, index,
len - index - 1);
//设置新的数组
setArray(newElements);
return true;
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
removeRange 方法
//移除指定区间的元素
void removeRange(int fromIndex, int toIndex) {
//上锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
//获取数组副本
Object[] elements = getArray();
//获取数组长度
int len = elements.length;
//参数检查
if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
throw new IndexOutOfBoundsException();
//获取新的长度
int newlen = len - (toIndex - fromIndex);
//获取需要移动的数量,结束位置后面的所有元素都要往前移动
int numMoved = len - toIndex;
if (numMoved == 0)
//如果移动数量为0,表示移除的是末尾的元素
//只要拷贝前面的元素就行
setArray(Arrays.copyOf(elements, newlen));
else {
//移除的元素位置在前面
//创建新长度大小的数组
Object[] newElements = new Object[newlen];
//拷贝0到fromIndex的元素
System.arraycopy(elements, 0, newElements, 0, fromIndex);
//拷贝toIndex到末尾的元素
System.arraycopy(elements, toIndex, newElements,
fromIndex, numMoved);
//设置新的数组
setArray(newElements);
}
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
addIfAbsent 方法
//添加一个不存在的元素
public boolean addIfAbsent(E e) {
//获取数组副本
Object[] snapshot = getArray();
//如果元素存在返回false
//元素不存在,调用addIfAbsent方法添加
return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
addIfAbsent(e, snapshot);
}
//在指定的数组中添加一个指定元素
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);
for (int i = 0; i < common; i++)
if (current[i] != snapshot[i] && eq(e, current[i]))
//如果元素被其它线程添加进来,直接返回false
//current[i] != snapshot[i]表示其中有个被修改
//eq(e, current[i]) 表示当前数组中已经存在指定对象e
return false;
if (indexOf(e, current, common, len) >= 0)
//如果已经存在指定对象直接返回false
return false;
}
//创建一个新的数组,长度为len+1
Object[] newElements = Arrays.copyOf(current, len + 1);
//把指定元素添加到新数组的末尾
newElements[len] = e;
//设置新的数组
setArray(newElements);
return true;
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
containsAll 方法
//查看是否包含指定集合中所有的元素
public boolean containsAll(Collection<?> c) {
//获取数组副本
Object[] elements = getArray();
//获取数组的长度
int len = elements.length;
//for循环遍历传入的集合
for (Object e : c) {
if (indexOf(e, elements, 0, len) < 0)
//如果有元素不存在,返回false
return false;
}
//都存在,返回true
return true;
}
复制代码
removeAll 方法
//移除集合中所有的元素
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;
//创建一个长度为len的数组,来存放未被删除的数组,数组真实数据长度为newlen
Object[] temp = new Object[len];
//for循环遍历
for (int i = 0; i < len; ++i) {
//获取当前位置的元素
Object element = elements[i];
if (!c.contains(element))
//如果集合中不包含当前元素
//把添加元素添加到新数组中去,并把newlen加1
temp[newlen++] = element;
}
if (newlen != len) {
//如果新数组中有元素
//把新数组中的有效元素拷贝到数组中去
setArray(Arrays.copyOf(temp, newlen));
return true;
}
}
return false;
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
retainAll 方法
//设置指定集合和当前数组的交集
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) {
//如果数组中有元素
// temp array holds those elements we know we want to keep
//新的长度
int newlen = 0;
//创建一个长度为len的数组,来存放交集的数据,数组真实数据长度为newlen
Object[] temp = new Object[len];
//for循环遍历
for (int i = 0; i < len; ++i) {
//获取当前位置的元素
Object element = elements[i];
if (c.contains(element))
//如果集合中包含当前元素
//把添加元素添加到新数组中去,并把newlen加1
temp[newlen++] = element;
}
if (newlen != len) {
//如果新数组中元素数量不等于当前数组元素数量
//把新数组中的有效元素拷贝到数组中去
setArray(Arrays.copyOf(temp, newlen));
return true;
}
}
return false;
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
addAllAbsent 方法
//添加指定集合中,当前数组不存在的元素
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;
//需要添加的数量,c中元素在当前数组中不存在的数量(差集?)
int added = 0;
// uniquify and compact elements in cs
//for循环遍历
for (int i = 0; i < cs.length; ++i) {
//获取cs中对应的元素
Object e = cs[i];
if (indexOf(e, elements, 0, len) < 0 &&
indexOf(e, cs, 0, added) < 0)
//当前元素不存在当前数组,并且也不存在在cs被覆盖的前面区域中
//把当前元素移动到cs的前面区域
cs[added++] = e;
}
if (added > 0) {
//如果cs中存在当前数组不存在的元素
//创建一个新数组,长度为len+added
//把当前数组的元素拷贝到新数组中
Object[] newElements = Arrays.copyOf(elements, len + added);
//把cs覆盖的前面区域的数据拷贝到新数组中
System.arraycopy(cs, 0, newElements, len, added);
//设置新的数组
setArray(newElements);
}
//返回添加的数量(当前数组不包含传入集合中的元素数量)
return added;
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
clear 方法
//清除所有元素
public void clear() {
//上锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
//直接设置一个长度为0的新数组
setArray(new Object[0]);
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
addAll 方法
//添加指定集合中的所有元素
public boolean addAll(Collection<? extends E> c) {
//把集合转换为数组
Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ?
((CopyOnWriteArrayList<?>)c).getArray() : c.toArray();
if (cs.length == 0)
//如果传入的集合为空,直接返回false
return false;
//上锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
//获取数组副本
Object[] elements = getArray();
//获取数组的长度
int len = elements.length;
if (len == 0 && cs.getClass() == Object[].class)
//如果当前数组长度为0 并且传入的集合元素为Object类
//直接设置传入集合转换的数组为新的数组
setArray(cs);
else {
//把当前数组扩容到len+cs.length,并把原数组元素拷贝到新的数组
Object[] newElements = Arrays.copyOf(elements, len + cs.length);
//把转换数组的元素拷贝到新数组尾部
System.arraycopy(cs, 0, newElements, len, cs.length);
//设置新的数组
setArray(newElements);
}
return true;
} finally {
//释放锁资源
lock.unlock();
}
}
//在指定位置添加指定集合中的所有元素
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);
//如果传入的集合为空,直接返回false
if (cs.length == 0)
return false;
//计算移动数量
//相当于把指定位置后面的所有元素向后移动传入集合的长度,把中间空出来存放集合元素
int numMoved = len - index;
Object[] newElements;
if (numMoved == 0)
//如果移动元素为0,表示在尾部添加。跟上面的方法一样
//把当前数组扩容到len+cs.length,并把原数组元素拷贝到新的数组
newElements = Arrays.copyOf(elements, len + cs.length);
else {
//在前面添加集合的情况
//创建新的数组,长度为len + cs.length
newElements = new Object[len + cs.length];
//拷贝0到index的元素到新数组
System.arraycopy(elements, 0, newElements, 0, index);
//拷贝index到length的元素到新数组末尾
System.arraycopy(elements, index,
newElements, index + cs.length,
numMoved);
}
//把传入集合的元素拷贝到新数组的中间,拷贝起始位置在index,长度为集合的长度
System.arraycopy(cs, 0, newElements, index, cs.length);
//设置新的数组
setArray(newElements);
return true;
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
forEach 方法
//遍历元素执行操作
public void forEach(Consumer<? super E> action) {
if (action == null) throw new NullPointerException();
Object[] elements = getArray();
int len = elements.length;
//for循环遍历元素。并对遍历元素执行action操作
for (int i = 0; i < len; ++i) {
@SuppressWarnings("unchecked") E e = (E) elements[i];
action.accept(e);
}
}
复制代码
removeIf 方法
//移除符合条件的元素
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循环遍历
for (int i = 0; i < len; ++i) {
@SuppressWarnings("unchecked") E e = (E) elements[i];
if (!filter.test(e))
//如果当前遍历元素不符合条件
//把当前元素添加到新数组
//移除相当于把不符合条件的留下来
//新数组元素数量加1
temp[newlen++] = e;
}
if (newlen != len) {
//如果新数组元素数量不等于旧数组元素数量
//把新数组的元素数量拷贝出来,并设置新的数组
setArray(Arrays.copyOf(temp, newlen));
return true;
}
}
return false;
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
replaceAll 方法
//替换所有元素,对每个元素进行操作
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];
//使用传入的operator操作当前遍历元素
newElements[i] = operator.apply(e);
}
//设置新数组
setArray(newElements);
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
sort 方法
//根据传入的Comparator对象排序
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);
//强转新的数组为泛型对象
@SuppressWarnings("unchecked") E[] es = (E[])newElements;
//调用Arrays.sort对象对新数组排序
Arrays.sort(es, c);
//设置新数组
setArray(newElements);
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码
toString 方法
public String toString() {
//调用Arrays.toString方法
return Arrays.toString(getArray());
}
复制代码
equals 方法
public boolean equals(Object o) {
if (o == this)
//如果引用相等,直接返回true
return true;
if (!(o instanceof List))
//如果不是List类型,返回false
return false;
List<?> list = (List<?>)(o);
//获取传入对象的迭代器
Iterator<?> it = list.iterator();
Object[] elements = getArray();
int len = elements.length;
//for循环遍历
for (int i = 0; i < len; ++i)
//使用eq方法比较两个遍历对象
//这里也比较了两个集合的长度
if (!it.hasNext() || !eq(elements[i], it.next()))
return false;
if (it.hasNext())
//传入的集合还有元素,表示长度不一样
return false;
return true;
}
复制代码
hashCode 方法
public int hashCode() {
int hashCode = 1;
Object[] elements = getArray();
int len = elements.length;
//循环获取每个元素的hashcode
//s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
for (int i = 0; i < len; ++i) {
Object obj = elements[i];
//注意这里出现了31,优质质数,String的hashcode也使用的它
hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
}
return hashCode;
}
复制代码
subList 方法
//获取起始位置到结束位置的子集
public List<E> subList(int fromIndex, int toIndex) {
//上锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
//获取数组副本
Object[] elements = getArray();
//获取数组的长度
int len = elements.length;
//参数检查
if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
throw new IndexOutOfBoundsException();
//通过COWSubList来创建子集
return new COWSubList<E>(this, fromIndex, toIndex);
} finally {
//释放锁资源
lock.unlock();
}
}
复制代码