JAVA深化篇_17—— 面试必问之ArrayList源码分析
ArrayList源码分析
ArrayList底层是用数组实现的存储
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
/**
* 默认初始容量。数组初始大小
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 用于空实例的共享空数组实例。
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 用于默认大小的空实例的共享空数组实例。
* 我们将其与EMPTY_ELEMENTDATA区分开来,以了解添加第一个元素时要膨胀多少。
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* 存储数组列表元素的数组缓冲区。数组列表的容量是此数组缓冲区的长度。
* 添加第一个元素时,任何带有 elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的空
* ArrayList 都将扩展到 DEFAULT_CAPACITY。
*
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* 数组列表的大小(它包含的元素数)。
*/
private int size;
/**
* 构造初始容量为 10 的空列表。
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* 将指定的元素追加到此列表的末尾。
* 形参:e – 要附加到此列表的元素
* 返回值:真 (由 指定 Collection.add)
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
//判断是否需要扩容,数组中的元素个数减数组长度,如果大于0表明需要扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* 增加容量以确保它至少可以容纳最小容量参数指定的元素数。
* 形参:minCapacity – 所需的最小容量
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
- Gdk1.8以后对数组的初始化方式采用的是延迟初始化,当添加第一个元素时才会初始化,而且数组长度默认为10
- 当ArrayList容器进行扩容时,是以当前长度的1.5倍进行扩容的