Java自学笔记—ArrayList源码初探
空参构造器
使用空参构造器new一个对象,并追源码查看其创建过程
public class ArrayListSource {
@SuppressWarnings("all")
public static void main(String[] args) {
ArrayList list = new ArrayList();
for (int i = 0; i <= 10 ; i++) {
list.add(i);
}
System.out.println(list);
}
}
追入new ArrayList();
,如下
// 无参构造器
ArrayList list = new ArrayList();
//创建一个空的elementDate数组 = {},
public ArrayList() {
// DEFAULTCAPACITY_EMPTY_ELEMENTDATA元素数组
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// EFAULTCAPACITY_EMPTY_ELEMENTDATA(默认空元素数组)
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
由源码可以调用ArrayList
空参构造器时,会创建一个空数组elementData[ ] = { }
使用add()方法添加元素
// for循环,添加10个数据
for (int i = 0; i <= 10 ; i++) {
list.add(i);
}
//装箱
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
//调用add()方法
public boolean add(E e) {
// ensureCapacityInternal(确认内部容量)
// 1.先确定是否要扩容,size不计算null
ensureCapacityInternal(size + 1); // Increments modCount!!
// 2.再赋值
elementData[size++] = e;
return true;
}
//确定minCapacity,第一次扩容为10
private void ensureCapacityInternal(int minCapacity) {
// 1.先判空,确定最小容量
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// 求最大值,用于确定最小容量
// DEFAULT_CAPACITY默认容量为10,minCapacity = size + 1
//空参起初size = 0 ,因此minCapacity为1
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
// 2.确认是否真的要扩容
ensureExplicitCapacity(minCapacity);
}
//确认是否真的要扩容
private void ensureExplicitCapacity(int minCapacity) {
// 1.记录当前集合被修改的次数,防止多个线程同时修改
modCount++;
// overflow-conscious code
// 2.如果最小容量比当前数组容量大,说明elementData容量不够,就要调用grow()扩容
if (minCapacity - elementData.length > 0)
// 扩容
grow(minCapacity);
}
// 扩容,使用扩容机制确认扩到多少,第一次newCapacity,第二次为1.5倍,扩容使用Arrays.copyOf()
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// oldCapacity >> 1 向右移动一位,相当于除于2,oldCapacity + (oldCapacity >> 1)为1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 第一次newCapacity为0,新容量比最小容量还小,则使用最小容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity; //赋值10
// 新容量比最大容量还大,调用hugeCapacity(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);
}
流程图如下
总结
ArrayList特点
- 存储在
transient Object[ ] elementDate
中, transient表示改属性不会被序列化,意为瞬时的,短暂的- 调用无参构造器 elementDate初始容量为0,第一次扩容为10,再次扩容为1.5倍,到15 -> 22(15 + 15/2)
- 指定大小构造器 elementDate初始容量为指定大小,再次扩容为1.5倍