ArrayList源代码深入剖析
1、 集合中存放的是对象的引用,无法放置原生数据类型,我们需要使用原生数据类型的包装类才能加入到集合当中。
2、 ArrayList底层采用数组实现,当使用不带参数的构造方法生成ArrayList对象时,实际上会在底层生成一个空的Object数组。
/**
* 存储ArrayList元素的数组缓冲区。
*ArrayList 的容量就是该数组缓冲区的长度。
* 任何elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA(此处比较的是数组的地址)的
*ArrayList ,当向其中增加第一个元素时就会将其容量扩张为 DEFAULT_CAPACITY(10)
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* 用于默认大小空实例的共享空数组实例。 We
* 用这个属性和EMPTY_ELEMENTDATA做区分 ,获知当追加第一个元素时该ArrayList容量扩大了多少
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
*构造一个初始容量为10的空列表。
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
3、 ArrayList add()方法
- 如果增加的元素个数超过了10个,那么ArrayList底层会生成一个数组,长度为原数组的1.5倍,然后将原数组的内容复制到新数组当中,并且后续增加的内容都会放到新数组当中。当新数组无法容纳增加的元素时,重复该过程。
/**
* 将特定的元素追加至list末尾
*
* @param e 待追加元素
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
*增加容量以确保它至少容纳最小容量参数指定的元素数量。
*
* @param minCapacity 所需的最小容量
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //右移一位,相当于除以2
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);
}