目录
1.1 ArrayList无参构造方法:将内部数组初始化为空数组。
1.2 ArrayList有参构造方法1:按照指定容量进行初始化
1.3 有参构造2: public ArrayList(Collection c):按照传入的Collection进行初始化
2.2、判断是否扩容方法ensureExplicitCapacity()、扩容核心方法grow()
前言
ArrayList实现了List接口,ArrayList
的底层是数组,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用ensureCapacity
操作来增加 ArrayList
实例的容量。
ArrayList源码理解
1.ArrayList构造方法
1.1 ArrayList无参构造方法:将内部数组初始化为空数组。
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//DEFAULTCAPACITY_EMPTY_ELEMENTDATA={};
}
1.2 ArrayList有参构造方法1:按照指定容量进行初始化
public ArrayList(int initialCapacity) {
//如果initialCapacity大于0,将该数组指向一个新的容量为initialCapacity的数组
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
//如果initialCapacity等于0,将该数组指向一个空数组
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
//其他情况抛出异常
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
1.3 有参构造2: public ArrayList(Collection<? extends E> c):按照传入的Collection进行初始化
public ArrayList(Collection<? extends E> c) {
//将传入的元素转换为数组
Object[] a = c.toArray();
//当长度不等于0时
if ((size = a.length) != 0) {
if (c.getClass() == ArrayList.class) {//判断数组类型
elementData = a;
} else {
elementData = Arrays.copyOf(a, size, Object[].class);
}
} else {
///如果长度为0,赋予空数组
// replace with empty array.
elementData = EMPTY_ELEMENTDATA;
}
}
2.ArrayList扩容
当我们通过ArrayList的add()方法给此集合添加元素时,如果集合满了应该怎么办呢,此时就涉及到ArrayList的动态扩容了。
2.1、add()方法
public boolean add(E e) {
//判断是否需要扩容
ensureCapacityInternal(size + 1); // Increments modCount!!
//添加元素
elementData[size++] = e;
return true;
}
2.2、判断是否扩容方法ensureExplicitCapacity()、扩容核心方法grow()
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
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);
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//如果还是空数组,最小容量为10和所需的最小容量的最大值
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
//如果最小容量大于数组的容量大小,则进行扩容
if (minCapacity - elementData.length > 0)
//传入最小容量,进行扩容
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//当前数组的容量大小
int newCapacity = oldCapacity + (oldCapacity >> 1);//新数组的容量,增加为之前的1.5倍
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;//新数组容量为所需的最小容量
if (newCapacity - MAX_ARRAY_SIZE > 0)
//调用hugeCapacity()方法,确保容量不会溢出
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
//如果所需的最小容量已经小于0,则表明已经超过了最大容量
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
//如果最小容量大于Integer.MAX_VALUE - 8,则返回Integer.MAX_VALUE,如果没有,则返回Integer.MAX_VALUE - 8
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
总结
1.如果数组为空数组,当第一次添加元素时,数组容量为10。
2.当数组容量不足时,按照原容量的1.5倍进行扩容。
3.当数组容量如果超出Integer.MAX_VALUE - 8和Integer.MAX_VALUE这个范围,则抛出错误。