欢迎使用CSDN-markdown编辑器

Arraylist 的动态扩容机制

当在 ArrayList 中增加一个对象时 Java 会去检查 Arraylist 以确保已存在的数组中有足够的容量来存储这个新对象(默认为 10,最大容量为 int 上限,减 8 是为了容错),如果没有足够容量就新建一个长度更长的数组(原来的1.5倍),旧的数组就会使用 Arrays.copyOf 方法被复制到新的数组中去,现有的数组引用指向了新的数组

//确保容量够用,内部会尝试扩容,如果需要
ensureCapacityInternal(size + 
1
)


//在未指定容量的情况下,容量为DEFAULT_CAPACITY = 10
//并且在第一次使用时创建容器数组,在存储过一次数据后,数组的真实容量至少DEFAULT_CAPACITY
private

void
 ensureCapacityInternal(
int
 minCapacity) {

//判断当前的元素容器是否是初始的空数组

if
 (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {

//如果是默认的空数组,则 minCapacity 至少为DEFAULT_CAPACITY
        minCapacity = 
Math
.max(DEFAULT_CAPACITY, minCapacity);
    }
    ensureExplicitCapacity(minCapacity);
}


//通过该方法进行真实准确扩容尝试的操作
private

void
 ensureExplicitCapacity(
int
 minCapacity) {
    modCount++; 
//记录List的结构修改的次数

//需要扩容

if
 (minCapacity - elementData.length > 
0
)
        grow(minCapacity);
}


//扩容操作
private

void
 grow(
int
 minCapacity) {

//原来的容量

int
 oldCapacity = elementData.length;

//新的容量 = 原来的容量 + (原来的容量的一半)

int
 newCapacity = oldCapacity + (oldCapacity >> 
1
);

//如果计算的新的容量比指定的扩容容量小,那么就使用指定的容量

if
 (newCapacity - minCapacity < 
0
)
        newCapacity = minCapacity;

//如果新的容量大于MAX_ARRAY_SIZE(Integer.MAX_VALUE - 8)

//那么就使用hugeCapacity进行容量分配

if
 (newCapacity - MAX_ARRAY_SIZE > 
0
)
        newCapacity = (minCapacity > MAX_ARRAY_SIZE) ? 
Integer
.MAX_VALUE : MAX_ARRAY_SIZE;


//创建长度为newCapacity的数组,并复制原来的元素到新的容器,完成ArrayList的内部扩容
    elementData = 
Arrays
.copyOf(elementData, newCapacity);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值