为了回答这个问题,我们来比较一下 ArrayList 和 ArrayDeque 类的 remove 方法。
ArrayList 移除方法
public E remove(int index) {
this.rangeCheck(index);
++this.modCount;
E oldValue = this.elementData(index);
int numMoved = this.size - index - 1;
if (numMoved > 0) {
System.arraycopy(this.elementData, index + 1, this.elementData, index, numMoved);
}
this.elementData[--this.size] = null;
return oldValue;
}
ArrayDeque removeLast 方法
public E removeLast() {
E x = this.pollLast();
if (x == null) {
throw new NoSuchElementException();
} else {
return x;
}
}
ArrayDeque removeLast 方法调用 pollLast 方法
public E pollLast() {
int t = this.tail - 1 & this.elements.length - 1;
E result = this.elements[t];
if (result == null) {
return null;
} else {
this.elements[t] = null;
this.tail = t;
return result;
}
}
下面一步步解释ArrayList的remove方法:
- 检查输入的索引是否在数组的范围内
- 将 ModCount 变量加一。
- 存储要删除的值。
- 确定要移动多少个数字(在我们的示例中,找到 numMoved 0 因为最后一个元素将被删除)。
- 如果要移动的数字大于 0,则复制数组(因为找到了 numMoved 0,所以不会执行复制)。
- 将 null 分配给数组的最后一个元素。
- 返回删除的值。
让我们一步一步解释 ArrayDeque removeLast 方法(解释 pollLast 方法就足够了):
- 查找数组的最后一个索引
- 返回数组最后一个元素的值。
- 如果最后一个元素的值等于 null,则返回 null。
- İ如果最后一个元素的值不为null(如果不为null,则会发生以下步骤)。
- 将 null 分配给最后一个元素
- 更新尾部变量的值
- 返回结果
当我们比较这些步骤时,在性能方面没有明显差异。在我们的示例中,ArrayList's System.copyarray
方法将不起作用,因为我们删除了最后一个元素。如果这种方法行得通,就会有性能差异。总之,除了@Gerald Mücke 的回答之外,没有其他需要考虑的区别。如果要删除的元素是列表的第一个元素,那么就会有性能差异。当我们要删除第一个元素时,可以使用类的removeFirst
方法ArrayDeque
。(该removeFirst
方法的工作原理与该方法类似removeLast
)。当我们想删除 ArrayList 中的第一个元素时,我们可以使用remove(0)
方法。当我们删除索引为 0 的 ArrayList 时,这一次数组 copy( System.copyarray
) 将完成。我们过去常说ArrayList
由于数组复制过程而速度较慢。