- 属性
/**
* 默认容量
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 默认空数组
* 初始化或者指定容量为0时,默认返回
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 默认空数组
* 初始化无参构造,默认返回
* 它与EMPTY_ELEMENTDATA的区别就是:该数组是默认返回的,而后者是在用户指定容量为0时返回。
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* 集合的容量
* 集合中添加的元素在该数组里
*/
transient Object[] elementData;
/**
* 集合实际的大小 空元素不算 故size<= elementData.length
*/
private int size;
- 构造方法
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
先看无参构造,默认集合是一个空数组,容量为0,此时可以用反射输出容量为0
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
有参构造,如果initialCapacity>0 就返回一个容量为initialCapacity的数组
如果initialCapacity=0 就返回一个空数组
同样可以用反射输出该集合的elementData的长度,即集合的容量。
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
该构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
- 扩充机制
默认容量 DEFAULT_CAPACITY = 10,何时被用到呢?来看add方法
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
add的时候用了ensureCapacityInternal() 这个方法,下面看这个方法
private void ensureCapacityInternal(int minCapacity) {
//如果集合容量为空集合
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//minCapacity 为 默认容量10 和 minCapacity中的 较大的那个
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
// 记录修改次数 modCount++
modCount++;
// 确保指定的容量 > 数组当前的容量 否则不需要扩容 直接 elementData[size++] = e;
if (minCapacity - elementData.length > 0)
// 扩容
grow(minCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
// 扩容
private void grow(int minCapacity) {
// 当前数组的容量
int oldCapacity = elementData.length;
// 新容量 = 当前容量 + 当前容量/2 =
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果扩容后 容量还是不够
if (newCapacity - minCapacity < 0)
新容量 = 指定的数组容量
newCapacity = minCapacity;
//如果扩容后的容量大于临界值,则进行大容量分配
if (newCapacity - MAX_ARRAY_SIZE > 0)
//大容量 分配
newCapacity = hugeCapacity(minCapacity);
//复制指定的数组内容以达到扩容的目的,该方法对不同的基本数据类型都有对应的重载方法,详见 java api
elementData = Arrays.copyOf(elementData, newCapacity);
}
// 大容量分配 最大为Integer.MAX_VALUE
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方法时,会先去检查集合容量,
(1)如果容量为空,
要添加的容量 小于 默认容量10 则集合容量扩容默认容量10
要添加的容量 大于 默认容量10 则集合容量扩容至 要添加的容量
(2)如果容量不为空,
要添加的容量 小于 当前容量 不扩充
要添加的容量 大于 当前容量 1.5倍扩充,如果还不够 ,大容量分配扩充