HashMap中remove()方法的源码分析
下文笔者讲述HashMap中remove方法的源码分析,如下所示
System.arraycopy()方法的功能
HashMap中remove()方法实现原理
实现思路:
1.删除指定位置上的元素
2.将后面的元素依次向前移动
源码如下所示
//根据索引删除指定位置的元素
public E remove(int index) {
//检查index的合理性
rangeCheck(index);
//这个作用很多,比如用来检测快速失败的一种标志。
modCount++;
//通过索引直接找到该元素
E oldValue = elementData(index);
//计算要移动的位数。
int numMoved = size - index - 1;
if (numMoved > 0)
//移动元素,挨个往前移一位。
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
//将--size上的位置赋值为null,让gc(垃圾回收机制)更快的回收它。
elementData[--size] = null; // clear to let GC do its work
//返回删除的元素。
return oldValue;
}
//从此列表中删除指定元素的第一个匹配项,如果存在,则删除
//通过元素来删除该元素,就依次遍历
//如果有这个元素,就将该元素的索引传给fastRemove(index)
//使用这个方法来删除该元素
//fastRemove(index)方法的内部跟remove(index)的实现一样
//这里最主要是知道arraylist可以存储null值
public boolean remove(Object o) {
if (o == null) {
//挨个遍历找到目标
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
//快速删除
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
//内部方法,“快速删除”,就是把重复的代码移到一个方法里
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
//删除或者保留指定集合中的元素
//用于两个方法,一个removeAll():它只清除指定集合中的元素,retainAll()用来测试两个集合是否有交集。
private boolean batchRemove(Collection<?> c, boolean complement) {
//将原集合,记名为A
final Object[] elementData = this.elementData;
//r用来控制循环,w是记录有多少个交集
int r = 0, w = 0;
boolean modified = false;
try {
//遍历 ArrayList 集合
for (; r < size; r++)
//参数中的集合c一次检测集合A中的元素是否有
if (c.contains(elementData[r]) == complement)
//有的话,就给集合A
elementData[w++] = elementData[r];
} finally {
//发生了异常,直接把 r 后面的复制到 w 后面
if (r != size) {
//将剩下的元素都赋值给集合A
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
//这里有两个用途,在removeAll()时,w一直为0,就直接跟clear一样,全是为null。
//retainAll():没有一个交集返回true
//有交集但不全交也返回true,而两个集合相等的时候,返回false
//不能根据返回值来确认两个集合是否有交集,而是通过原集合的大小是否发生改变来判断
//如果原集合中还有元素,则代表有交集,而元集合没有元素了,说明两个集合没有交集。
// 清除多余的元素,clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
//保留公共的
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, true);
}
//将elementData中每个元素都赋值为null,等待垃圾回收将这个给回收掉
public void clear() {
modCount++;
//并没有直接使数组指向 null,而是逐个把元素置为空,下次使用时就不用重新 new 了
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
相关阅读:System.arraycopy()方法的功能
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


