ArrayList移除元素方法remove

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-23 23:20   11   0

ArrayList提供添加元素的方法,同时也提供了移除元素的方法。移除元素比较简单只是元素的移动,然后将最后一个元素赋值为null,交给垃圾回收机制回收。并且size减小

第一个是移除指定索引位置的元素。并且返回移除的元素

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

第二个是移除一个指定的对象

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
    }

在删除指定对象时使用了fastRemove(index);方法,因为这里索引是确定的,不会有索引越界的问题,因此这个方法里少了对索引的检查,直接移除元素。

clear删除所有元素,这个方法其实很简单,直接将所有元素置换为null

public void clear() {
        modCount++;

        // clear to let GC do its work
        //循环遍历所有元素
        for (int i = 0; i < size; i++)
           //置空
            elementData[i] = null;

        size = 0;
    }

还有一个删除指定集合的元素的方法

public boolean removeAll(Collection<?> c) {
        //调用Objects的静态方法判断非空
        Objects.requireNonNull(c);
        //调用batchRemove()方法移除元素
        return batchRemove(c, false);
    }

//Objects对象静态方法,为空抛出异常
public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        //否则返回当前对象
        return obj;
    }

//batchRemove方法,进行移除元素的动作
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;
    }

转载于:https://my.oschina.net/jettyWang/blog/912025

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP