今天在阅读jdk源码时,阅读到ArrayList这个类时,阅读到此方法,觉得对ArrayList类的理解很有帮助,特此记录并分享
作用:
本人解释:用于扩展ArrayList容量。参数 int minCapacity:为需要扩展到多大容量,(这里要注意下,是扩展到多大,而不是在原来基础上叠加多大)
官方解释: 如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。参数:minCapacity
- 所需的最小容量
结合代码做具体解释:(重点来了!!!)
/**
* 默认初始容量.
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 用于空实例的空数组实例。如 ArrayList list = new ArrayList<>() list就等于{}.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public void ensureCapacity(int minCapacity) {
//判断需要扩容的数组是否为空实例(空数组)如果为不为空,则变量等于0.为空则变量等于数组默认容量 10
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
? 0
: DEFAULT_CAPACITY;
//如果需要扩容的量大于定义的变量。则进一步调用以下方法。
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
//需要扩容的量大于原数组的长度,则进一步调用方法。(其实这里就本文章对ensureCapacity()
//分析来说,我觉得这个方法完全写在上面的方法中,没必要再单独再写个方法做判断。)
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; //原数组的长度
int newCapacity = oldCapacity + (oldCapacity >> 1); //原数组的长度+原数组的长度/2
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity; // 系统给予的扩容策略所扩的容量<用户给的扩容量,则改用用户指定扩容量
if (newCapacity - MAX_ARRAY_SIZE > 0)
// 如果需要扩容的量大于了本类中定义的最大扩容限制,则扩容到 int 类型最大长度
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);// 扩容,其实调用的的是数组的复制方法
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0)
throw new OutOfMemoryError();
// 如若需要扩容的量大于了最大限制,则扩容量改为 int 最大限制量:2147483647。否则为本类中所限制长度:2147483647-8
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
关于方法的注释就全在上面了。
说明:
(1)、由源码可以看出,系统的默认扩容是扩容为原数组长度的1.5倍。
(2)、若用户手动设置的扩容量大于了默认的扩容策略,则扩容量改为用户设置的。
(3)、若用户手动设置的扩容量小于了默认的扩容策略,还是使用默认扩容策略。
讨论:
关于源码中我所提及的:【其实这里就本文章对ensureCapacity()分析来说,我觉得这个方法完全写在上面的方法中,没必要再单独再写个方法做判断】 这个点,我个人觉得在这里可以写成如下形式
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
? elementData.length: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
modCount++;
grow(minCapacity);
}
}
当然了,可能我的想法不一定对,可能还有错。若各位发现有不足之处,希望您指点指点。