ArrayList 底层原理分析--扩容

ArrayList类的多态

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

AbstractList

AbstractList继承AbstractCollection,实现List接口,因此除了具有集合的方法属性外,还具有固定顺序,以及索引特征。
AbstractList源码中包含了四个类Itr ,ListItr,SubList,RandomAccessSubList,分别来支持迭代和获取子列表。

RandomAccess

这个是一个随机访问,所谓的随机访问就是访问集合里面随机一个元素。当然所有的集合都具有随机访问的功能,但是基于基本结构的不同,实现的速度不同。ArrayList基于数组实现,天然带下标,可以实现常量级的随机访问,复杂度为O(1)。

Cloneable

Cloneable 接口和普通的接口不同,他只是用于标记类的使用者了解克隆过程。
如果一个对象请求克隆, 但没有实现Cloneable接口, 就会生成一个CloneNotSupportedException异常。

Serializable

这是在程序中为了能直接以 Java 对象的形式进行保存,然后再重新得到该 Java 对象,这就是序列化能力Serializable。当然,并不是所有的类都需要序列化,一般来说当需要远程调用的时候就需要把类给序列化进行传输。

成员变量

序列化编号

private static final long serialVersionUID

ArrayList默认初始容量

private static final int DEFAULT_CAPACITY = 10;

用于空实例的共享空数组实例。

private static final Object[] EMPTY_ELEMENTDATA = {};

用于默认大小的空实例的共享空数组实例。将其与EMPTY_ELEMENTDATA区分开来,以知道添加第一个元素时要扩容多少。

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

存储数组列表元素的数组缓冲区。数组列表的容量就是这个数组缓冲区的长度。任何带有elementData = = DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空数组列表在添加第一个元素时将被扩展为DEFAULT_CAPACITY。

transient Object[] elementData;

数组列表的大小(包含的元素数量)。

 private int size;

构造方法

指定容量大小的

public ArrayList(int initialCapacity)

无参构造的

public ArrayList()

指定集合元素类型的

public ArrayList(Collection<? extends E> c)

扩容

重头戏,ArrayList自动扩容的原理
应该不难理解吧,新的容量等于就的容量的1.5倍,>>1是位运算,也就是除以二。

第一个判断是 检查新容量是否大于最小需要容量,若还是小于最小需要容量,那么就把最小需要容量当作数组的新容量

第二个判断是 如果新容量大于 MAX_ARRAY_SIZE,进入(执行) hugeCapacity() 方法来比较 minCapacity 和 MAX_ARRAY_SIZE, 如果minCapacity大于最大容量,则新容量则为Integer.MAX_VALUE,否则,新容量大小则为 MAX_ARRAY_SIZE 即为 Integer.MAX_VALUE - 8
其实这个判断主要是在数组非常大的时候,接近 2的31次方减1的时候。MAX_ARRAY_SIZE的值就是2的31次方减1。

private void grow(int minCapacity){
 // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        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);}

其他的底层方法就略过了。