ArrayList源码分析
ArrayList源码分析
ArrayList是collection下的集合,底层是动态数组实现,其中的数据可以重复
初始化
ArrayList初始化,有三种方式,一般不指定容量的情况下,初始化只会将空元素集合赋值给相应的元素数据集合,
// 所以,初始化的集合,容量为0,是一个Object类型的数组,故集合不能存储基础数据类型
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
如果指定类集合的长度,则会直接创建一个相应大小的Object对象数组
扩容机制
ArrayList的扩容有两个位置
- 使用无参构造创建集合,第一次添加元素时,会对集合进行判断,如果为空,则对添加元素所需的容量与默认容量进行比较,默认容量为10
- 添加元素时,容量不足时,会进行扩容。此为核心扩容机制
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
// 新的容量为旧容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果新容量小于所需的最小容量,则扩容后的容量为所需最小的容量
if (newCapacity - minCapacity < 0){
newCapacity = minCapacity;
}
// 如果新容量大于集合限制的最大容量,则进入另一判断:看所需的容量大小
if (newCapacity - MAX_ARRAY_SIZE > 0){
newCapacity = hugeCapacity(minCapacity);
}
// 创建一个新的数组,将旧数组copy进去
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
添加与获取元素
add: 增加元素的核心在于集合的扩容机制
get: 因为集合的本质是一个Object数组,所以直接返回相应位置的元素即可
remove: 移除元素不会改变数组的容量,但是数组中元素的位置会进行相应的变化
注:Java版本为1.8
第一要有志,第二要有识,第三要有恒。