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(); } } 复制代码
原文
https://juejin.im/post/5e721365e51d4527271eb696
本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Java 并发编程(十八) — CopyOnWriteArrayList 源码分析