ArrayList的源码简单分析
ArrayList的源码简单分析
ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable
支持序列化
初始默认容量10
内部有两个空对象
Object[] EMPTY_ELEMENTDATA = {} -- 调用构造函数传入的容量是零的时候使用
Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {} -- 调动构造函数没有指定容量大小的时候默认
transient Object[] elementData;
在未指定容量的时候,默认elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA,当add的时候默认扩容到10
size -- 多少个元素
可以存入null元素
E set(int index, E element) -- 使用新元素替换指定位置的老元素,并返回老元素
void add(int index, E element) -- 在指定位置插入新元素,老元素及其后面的元素统一后移。
E remove(int index) -- 删除指定位置的元素,其后元素统一前移。
boolean removeAll(Collection<?> c) -- 删除所有在c里面的元素
boolean retainAll(Collection<?> c) -- 删除所有不在c里面的元素
扩容的过程,以调用ArrayList默认无参构造为例。
(1)在第一次add的时候,默认List大小为空,首次扩到10个容量
(2)然后扩容按照原容量的1.5倍扩容,比如:10,15,22,33...
存储的上限是Integer.MAX_VALUE,而不是Integer.MAX_VALUE - 8;
这地方有段解释:
源码中显示了最大容量时Integer.MAX_VALUE - 8;
要分配的最大数组大小,有些虚拟机在数组中保留一些头字。尝试分配较大的数组可能会导致OutOfMemoryError:请求的数组大小超过VM限制
意思就是有些虚拟机时需要占用一部分空间来存对象头的(我的理解),Java为了保证不会出现OOM,所以就出现了Integer.MAX_VALUE - 8;但是我们要注意到是有些
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
hugeCapacity方法中会来判断最小需要的容量和MAX_ARRAY_SIZE的关系,若是小于,那么就使用
MAX_ARRAY_SIZE来防止出现OOM,但是要是还不够,那么就对不起了,你想要就给你,就直接给Integer.MAX_VALUE了