ArrayList底层维护的是一个动态数组,每个ArrayList实例都有一个容量,并随着往ArrayList里面添加元素,其容量也自动增长。
下面通过ArrayList源码分析其原理。
以下代码取自JDK1.8
2.代码分析
注:请阅读代码注释结合代码来看
1.主要变量
transient Object[] elementData;
// 真正存储数据的数组,整个ArrayList的元素数据都存在这个Object[]中.
private int size;
// 实际ArrayList存储数据的元素大小(非容量).
2.构造函数
//指定ArrayList的大小
public ArrayList(
int initialCapacity) {
if (initialCapacity >
0) {
// 指定数组大小(上面说了ArrayList是以elementData 存储元素数据的)
this.elementData =
new Object[initialCapacity];
}
else if (initialCapacity ==
0) {
// 指定一个空数组,没有任何大小(相当于只是声明了数组变量)
// private static final Object[] EMPTY_ELEMENTDATA = {};
this.elementData = EMPTY_ELEMENTDATA;
}
else {
throw new IllegalArgumentException(
"Illegal Capacity: "+
initialCapacity);
}
}
public ArrayList() {
// 指定一个空数组,没有任何大小(相当于只是声明了数组变量)
// private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//传入一个集合
public ArrayList(Collection<? extends E> c) {
// 返回包含此 collection 中所有元素的数组
elementData = c.toArray();
if ((size = elementData.length) !=
0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
// 复制指定的数组,返回包含相同元素和长度的Object类型的数组
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
else {
// 指定一个空数组,没有任何大小(相当于只是声明了数组变量)
// private static final Object[] EMPTY_ELEMENTDATA = {};
this.elementData = EMPTY_ELEMENTDATA;
}
}
1) ArrayList()
构造一个没有指定大小的空列表(相当于只是声明了数组变量)。
2) ArrayList(int initialCapacity)
initialCapacity不为 0 时构造一个具有指定初始容量的空列表。
如果initialCapacity指定为 0 ,那么还是同ArrayList()一样。
3) ArrayList(Collection c)
(注:因此处代码放入会影响显示,只需知道是最后一个传入Collection的方法即可,见上面的代码块最后一个方法)
构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
3.add方法
public boolean add(E e) {
ensureCapacityInternal(size +
1);
//添加元素数据,为所存在的最大元素+1位置增加元素
elementData[size++] = e;
return true;
}
解说:上面代码块 add 方法调用ensureCapacityInternal(size + 1); 如下代码:
private void ensureCapacityInternal(
int minCapacity) {
// 如果数组是为空数组,那么设置当前数组默认容量
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//默认容量为:private static final int DEFAULT_CAPACITY = 10;
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
解说:上面代码块 ensureCapacityInternal 方法拿到了默认值为10的默认数组空间
然后调用ensureExplicitCapacity(minCapacity); 如下代码:
private void ensureExplicitCapacity(
int minCapacity) {
modCount++;
//假如是刚刚创建List<String> list1 = new ArrayList<String>();
// 当前容量10 - 所存元素大小0
if (minCapacity - elementData.length >
0)
grow(minCapacity);
}