这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战
初始化
无参数初始化:
public ArrayList() {
// 赋值默认空数组
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
复制代码
带参数初始化:
/**
* 根据给定容量初始化
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
// 参数大于0情况下直接创建该大小数组
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
}
}
/**
* 根据给定集合初始化
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
复制代码
新增、扩容机制
新增机制
- 确保数组长度足够
- 将元素追加到数组现有最后一位元素后面
- 容器大小+1
确保容量足够,如果当前数组长度不大于所需的最小长度,触发扩容操作
扩容机制
核心:新数组长度 = 旧数组长度 + 旧数组长度/2(向下取整)
整体描述新增扩容过程
-
确保数组长度足够存储接下来的一位元素。
- 计算出所需要的最小容量,如果大于现有的数组长度,开始扩容。
- 扩容细节:计算出新的数组长度(如果new capacity < 最小所需长度,将最小所需数组长度赋值);创建新数组,完成元素迁移工作。
-
容器存储元素大小 + 1,将元素添加到数组中元素尾巴上。
批量删除
从ArrayList中删除另一个集合中的所有元素
双指针法:定义两个变量r、w,遍历elementData,以r记录遍历元素位置,w记录重新赋值元素的位置
遍历结束后,将w位置之后的元素全部置为null,表示删除元素。
int r = 0, w = 0;
for (; r < size; r++)
if (!c.contains(elementData[r]))
elementData[w++] = elementData[r];
for (int i = w; i < size; i++)
elementData[i] = null;
复制代码