从面试角度聊聊 ArrayList 中的 remove 方法

先看一段代码,看看自定义的ArrayList中的remove设计是否有问题。

public class MyArrayList {
    private Object[] mData = new Object[0];
    private int mSize = 0;
    // 删除第i个元素
    public void remove(int i) {
        if (i < 0 || i >= mSize) return;
        for (int index = i; index < mSize - 1; index++) {
            mData[index] = mData[index + 1];
        }
        --mSize;
    }
    // ... 其他方法略
}

走进源码:

针对remove,有两种方式实现

(1)根据位置删除,代码如下所示:

    public E remove(int index) {
        rangeCheck(index);
 
        modCount++;
        E oldValue = elementData(index);
 
        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
 
        return oldValue;
    }

实现步骤:

  • 检查所要移除的位置是否落在数组元素长度之内。
  • 修改次数+1
  • 把需要删除的元素赋给oldValue,一遍方法返回旧元素
  • numMoved计算出的是删除元素后需要移动的元素数。
  • 当numMoved>0 说明删除元素后需要把后面的元素往前移动。
  • 当numMoved<0 时,说明删除的元素为最后一个元素。
  • 直接把最后一个位置置空。(分析重点:将最后的位置要设置为空,让垃圾回收器回收 ,防止对象游离)
  • 返回被删值

(2)根据内容删

参考资料:

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;
}

其中的fastRemove,代码如下:

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
}

实现步骤:

  • 因为对象是否相等需要使用equals方法,但是空对象不能使用equals方法比较。
  • 因此需要先判断传入的对象是否为空。
  • 为空时 使用==来寻找数组中空对象并删除。
  • 不为空时,便使用equals遍历寻找来删除相应对象。

OK,ArrayList的第一阶段的研究到此结束,针对开头的问题,已经找到了答案。

remove的设计有问题,–mSize;之后需要把mData[–mSize]=null;让垃圾回收器回收 ,防止对象游离。

未来有时间的研究方向大概如下,

  • ArrayList VS LinkedList

  • 如何自定义一个ArrayList

ArrayList的研究有时间可以再深入了解一下。网上的文章已经很多,在此不在赘述。旨在加深自我认知,上述大家如有疑问,欢迎PK。

参考资料:

1.解读ArrayList中的add和remove方法

2.自定义一个ArrayList类

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小羊子说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值