这里再放一下之前的集合框架结构图的一部分:
这篇文章将要介绍图中橙色方框框起来的 ArrayList
类。
一、一些特点
- 可存储重复元素:
ArrayList
允许存储重复的元素,多个相同的对象可以存在于同一个列表中。 - 支持 null 值:
ArrayList
可以存储null
值,作为有效元素。 - 线程不安全:
ArrayList
是线程不安全的。在多个线程同时访问同一个ArrayList
的情况下,如果没有适当的同步机制,可能会导致数据的不一致性。
二、数据存储
ArrayList
使用一个 Object[]
数组来存储实际的元素。
三、构造器
- 创建一个空的ArrayList实例:
public ArrayList()
- 创建一个指定初始容量的ArrayList实例:
public ArrayList(int initialCapacity)
- 创建一个包含指定集合元素的ArrayList实例:
public ArrayList(Collection<? extends E> c)
四、扩容机制
想知道具体的扩容机制,我们要查看 ArrayList
的部分源码。
1、使用无参构造器开局
对于 ArrayList
的无参构造器:
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
};
这里的 DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
属性是一个空数组,所以说,如果使用无参构造器创建一个 ArrayList
的话,数组的空间为 0。
如果我们通过无参构造器创建了一个 elementData
为空的 ArrayList
,然后对它进行一些其他的操作,对应的扩容操作又是什么呢,我们下面将来探讨这一问题。
List<String> list = new ArrayList<String>();
list.add("Hello");
我们可以对这一段代码进行调试,当我们进入了 add()
方法内部时,我们可以看到 add()
方法的具体实现:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 确保内部有足够空间
elementData[size++] = e;
return true;
}
这里会首先调用 ensureCapacityInternal()
方法,用来确保有足够的空间,ensureCapacityInternal()
方法的具体实现:
private void ensureCapacityInternal(int minCapacity) {
// 这里 minCapacity 为 size + 1
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
这里首先判断数组是不是还是 DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}
,也就是说判断数组是不是还是空数组,如果是空数组的话,确定 minCapacity
为 DEFAULT_CAPACITY, minCapacity
两者之间最大值,这里由于 minCapacity
是 size + 1
为 1,而 DEFAULT_CAPACITY
为10,所以 minCapacity
被赋值为 10。
然后接着向下执行,调用 ensureExplicitCapacity()
方法,此方法的具体实现为:
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0) // 如果最小需要空间大于数组的大小,则增大空间
grow(minCapacity);
}
这里由于 minCapacity
为 10,数组的大小为 0,所以接着执行 grow()
方法,此方法的具体实现为:
private void grow(int minCapacity) {
int oldCapacity = elementData.length; // 0
// 右移相当于整数除法中的除以二
int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5 * 0
if (newCapacity -