0
点赞
收藏
分享

微信扫一扫

Collections之Arraylist源码解读(六)

Collections之Arraylist源码解读(六)_数组

🍁 作者:知识浅谈,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:​​知识浅谈​​

举报

相关推荐

0 条评论