写点什么

ArrayList 源码分析 - 删除

作者:zarmnosaj
  • 2022 年 5 月 16 日
  • 本文字数:1451 字

    阅读完需:约 5 分钟

ArrayList 源码分析-删除

根据元素进行元素的删除:

    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;    }
复制代码


  1. if (o == null) 如果要删除的值是 null,找到第一个值是 null 的删除

  2. for (int index = 0; index < size; index++) 如果要删除的值不为 null,找到第一个和要删除的值相等的删除

  3. if(o.equals(elementData[index]) 这里是根据 equals 来判断值相等的,相等后再根据索引位置进行删除

根据索引位置进行元素的删除:

    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    }
复制代码


  1. 首先仍然是modCount++,记录数组的结构发生变动

  2. numMoved 表示删除 index 位置的元素后,需要从 index 后移动多少个元素到前面去

  3. 减 1 的原因表示 size 从 1 开始算起,index 从 0 开始算起

  4. System.arraycopy(elementData, index+1, elementData, index, numMoved)表示从 index +1 位置开始被拷贝,拷贝的起始位置是 index,长度是 numMoved

  5. elementData[--size] = null;数组最后一个位置赋值 null,帮助 GC 回收无用对象

  6. 从源码中,我们可以看出,某一个元素被删除后,为了维护数组结构,会把数组后面的元素往前移动

全部删除

    public boolean removeAll(Collection<?> c) {        Objects.requireNonNull(c);        return batchRemove(c, false);    }        private boolean batchRemove(Collection<?> c, boolean complement) {        final Object[] elementData = this.elementData;        int r = 0, w = 0;        boolean modified = false;        try {            for (; r < size; r++)                if (c.contains(elementData[r]) == complement)                    elementData[w++] = elementData[r];        } finally {            // Preserve behavioral compatibility with AbstractCollection,            // even if c.contains() throws.            if (r != size) {                System.arraycopy(elementData, r,                                 elementData, w,                                 size - r);                w += size - r;            }            if (w != size) {                // 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;    }
复制代码


  1. 首先进行空检验

  2. 对原数据进行循环校验,如果包含了 remove 元素,则进行替换

  3. 根据情况进行数组拷贝/数据全 set null

  4. 最后返回

用户头像

zarmnosaj

关注

还未添加个人签名 2020.02.06 加入

还未添加个人简介

评论

发布
暂无评论
ArrayList源码分析-删除_5月月更_zarmnosaj_InfoQ写作社区