写点什么

Collections 之 Arraylist 源码解读 (六)

作者:知识浅谈
  • 2022 年 10 月 06 日
    吉林
  • 本文字数:2321 字

    阅读完需:约 8 分钟


🍁 作者:知识浅谈,CSDN 博客专家,阿里云签约博主,InfoQ 签约博主,华为云云享专家

📌 擅长领域:全栈工程师、爬虫、ACM 算法

💒 公众号:知识浅谈


Collections 之 Arraylist 源码解读(六)总结


正菜来了⛳⛳⛳

🎈Arraylist 中的方法

🍮clear()

官方解释:Removes all of the elements from this list. The list will be empty after this call returns.其实这段代码,相对来说是比较简单的,就是把 ArrayList 中底层的数组全部置为 null,而不是把这个数组删除。


public void clear() {    modCount++;
// clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null;
size = 0;}
复制代码

🍮addAll(Collection<? extends E> c)

这个方法的含义也比较明显就是把 Collections 的对象添加到当前 ArrayList 中,同样在添加之前会先判断 elementData 数组中是否能够完整添加进这个数组,就是通过调用 ensureCapacityInternal 这个函数进行判断的。


public boolean addAll(Collection<? extends E> c) {    Object[] a = c.toArray();    int numNew = a.length;    ensureCapacityInternal(size + numNew);  // Increments modCount    System.arraycopy(a, 0, elementData, size, numNew);    size += numNew;    return numNew != 0;}
复制代码

🍮addAll(int index, Collection<? extends E> c)

  1. 这个和上边的很想,但是有一些差别就是,上边的是把新的集合中的元素按顺序添加到旧数组的后边而这个是有指定索引位置的,就是把集合中的元素按照指定索引的位置插入

  2. 将指定集合中的所有元素插入此列表,从指定位置开始。将当前位于该位置的元素(如果有)和任何后续元素向右移动(增加它们的索引)。新元素将按照指定集合的迭代器返回的顺序出现在列表中。


    public boolean addAll(int index, Collection<? extends E> c) {        rangeCheckForAdd(index);
Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved);
System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }
复制代码

🍮removeRange(int fromIndex, int toIndex)

  1. 函数含义:这个函数的理解也比较简单,从函数的结构上看,是移除 ArrayList 中的 fromIndex 索引到 toIndex 位置的元素。

  2. 但是底层的实现并不是把这些位置的元素移除,而是把 toindex 位置后的元素覆盖到 fromindex 开始的位置到 toindex 位置的元素,即 elementData 的大小并没有改变。


protected void removeRange(int fromIndex, int toIndex) {        modCount++;        int numMoved = size - toIndex;        System.arraycopy(elementData, toIndex, elementData, fromIndex,                         numMoved);
// clear to let GC do its work int newSize = size - (toIndex-fromIndex); for (int i = newSize; i < size; i++) { elementData[i] = null; } size = newSize; }
复制代码

🍮removeAll(Collection<?> c)

含义:从此列表中删除包含在指定集合中的所有元素


    public boolean removeAll(Collection<?> c) {        Objects.requireNonNull(c);        return batchRemove(c, false);    }
复制代码


从以上函数中可以看出,在删除的时候会调用 requireNonNull 这个函数,判断 c 是不是 null,如果为 null,就会抛出异常。然后调用 batchRemove 这个函数把 elementData 中的包含的 c 中的元素批量删除,接着看 batchRemove 这个函数。

🍮batchRemove(Collection<?> c, boolean complement)

含义:这个函数的意义就是从 elementData 数组中删除 c 中含有的元素。


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


上边代码最有用的是这个,仔细品一下可以看到,这个是把 elementData 中的元素,如果不在 c 集合中含有,就把这个元素移动到 w 的位置,w 表示的 elementData 数组的中不在 c 中含有的个数,这个思想在算法题中常用到。


for (; r < size; r++)   if (c.contains(elementData[r]) == complement)       elementData[w++] = elementData[r];
复制代码

🍚总结

以上是关于 ArrayList 中的相关函数的理解,希望对你有所帮助。Writed By:知识浅谈

发布于: 刚刚阅读数: 3
用户头像

知识浅谈

关注

公众号:知识浅谈 2022.06.22 加入

🍁 作者:知识浅谈,InfoQ签约作者,CSDN博客专家/签约讲师,华为云云享专家,阿里云签约博主 📌 擅长领域:全栈工程师、爬虫、ACM算法 💒 公众号:知识浅谈 🔥 联系方式vx:zsqtcc

评论

发布
暂无评论
Collections之Arraylist源码解读(六)_ArrayList_知识浅谈_InfoQ写作社区