大家好,我是顺亿。今天我们来聊聊ArrayList中的remove方法,这个方法可是ArrayList操作中经常用到的一个。下面,我会用我自己的风格,带你详细了解这个方法的工作原理和使用方法。
参数为元素下标(int型)的remove方法
首先,我们来看看参数为元素下标的remove方法。这个方法的工作原理是这样的:
- 先检查下标是否越界。
- 然后取出要删除的元素。
- 如果被删除的不是最后一个元素,就调用一个本地方法把数组向前移动一位。
- 最后,把列表大小减1,并把最后一个元素置空。
// 参数是下标
// 返回值是被删除的元素值
public E remove(int index) {
// 首先检查下标是否越界,rangeCheck(index)是个内部私有方法,如果下标越界,将抛出异常
rangeCheck(index);
// 当前列表的修改次数加1
modCount++;
// 根据下标获取对应的值
E oldValue = elementData(index);
// 计算要删除位置的元素后还有几个元素,用于后面的操作
int numMoved = size - index - 1;
// 如果要删除的元素不是最后一个元素
if (numMoved > 0)
// 这是jdk的一个本地方法,用于将一个数组从指定位置复制到目标数组的指定位置
// 其中numMoved就是要复制的个数,也就是被删除元素后面的元素个数
System.arraycopy(elementData, index+1, elementData, index, numMoved);
// 把列表大小减1,并把最后一个元素置空,让垃圾收集器把它回收
// 这里如果不置空,它将会保存着一个引用,那么垃圾收集器将无法回收它,可能会造成内存泄漏
elementData[--size] = null; // clear to let GC do its work
// 将被删除的值返回
return oldValue;
}
这个方法很简单,但是要注意的是,如果删除的不是最后一个元素,它会把后面的元素向前移动,这样会影响性能。
参数为对象的remove方法
接下来,我们来看看参数为对象的remove方法。这个方法其实是通过indexOf(Object o)和remove(int index)结合实现的。它的原理是先找到指定对象,然后根据下标删除对应的元素。
// 参数是对象
// 返回值为是否删除成功
public boolean remove(Object o) {
// 如果对象为空(ArrayList允许元素为空)
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;
}
fastRemove方法
fastRemove是一个私有删除方法,它跳过了边界检查并且不返回删除元素值。这个方法在remove(Object o)中被调用,可以提升一定的效率。
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
}
通过这篇文章,你应该对ArrayList的remove方法有了更深入的了解。如果你还有其他问题,欢迎在评论区留言,我会尽力解答。对了,别忘了关注趣航编程网(www.vqhf.com),这里有很多有趣的技术文章等着你。
