CopyOnWriteArrayList 源码分析 - 删除
指定索引位置删除
lock.lock();
首先进行加锁
E oldValue = get(elements, index);
取得即将删除的旧数据
if (numMoved == 0) setArray(Arrays.copyOf(elements, len - 1));
判断要删除的数据是否在数组的尾部,如果是则直接删除
Object[] newElements = new Object[len - 1]; System.arraycopy(elements, 0, newElements, 0, index); System.arraycopy(elements, index + 1, newElements, index, numMoved); setArray(newElements);
如果要删除的数据不在数组的尾部,则首先设置新数组的长度为原数组长度-1,然后从索引 0 位置开始,拷贝数组元素到尾部截止。
方法总结:
首先进行加锁
判断要删除数据的索引位置,然后选择不同的方式进行删除
最后进行解锁
整个方法使用 try-catch 进行包裹,能保证就算出现异常,锁也一定会被释放。
批量删除
源码:
if (c == null) throw new NullPointerException();
首先对要删除额元素集合进行空判断
lock.lock();
加锁
if (len != 0) { }
判断当前数组是否有值,如果当前数组不存在值的话则直接返回
int newlen = 0;
新数组的索引位置
for (int i = 0; i < len; ++i) { }
循环判断,将不存在于删除元素集合中的数据,放到新数组中
if (!c.contains(element)) temp[newlen++] = element;
判断每个元素是否存在于删除元素集合中
if (newlen != len) { setArray(Arrays.copyOf(temp, newlen)); return true; }
拷贝新数组,变相的删除了不包含在 c 中的元素
方法总结:集合元素批量删除并不会逐次调用指定元素删除的方法,而是先对原数组进行循环判断,把不需要删除的元素放到一个新数组,最后得到新数组就是结果。变相的达到了删除元素的目的。
评论