ArrayList扩容机制

简介: ArrayList 添加元素时,先调用 `ensureCapacityInternal()` 确保容量充足。首次添加时,最小容量为 1,经比较后扩容至默认值 10。后续添加元素时,若容量不足则触发 `grow()` 方法,将容量扩大为原来的 1.5 倍(通过位运算 `oldCapacity + (oldCapacity >> 1)` 实现),提升性能。扩容后赋值并返回 true。注意:`length` 用于数组,`length()` 用于字符串,`size()` 用于集合。

● 先来看Add方法
/* 将指定的元素追加到此列表的末尾
*/
public boolean add(E e) {
//添加元素之前,先调用ensureCapacityInternal方法
ensureCapacityInternal(size + 1); // Increments modCount!!(增量modCount)
//这里看到ArrayList添加元素的实质就相当于为数组赋值
elementData[size++] = e;
return true;
}
● 再来看看ensureCapacityInternal()方法,可以看到add()方法首先调用了ensureCapacityInternal(size+1)
//得到最小扩容量
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//获取默认的容量和传入参数的较大值(第一次的较大值是DEFAULT_CAPACITY=10,minCapacity=1)
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
当要add进第一个元素时,minCapacity为1,在Math.max()方法比较后,minCapacity为10
● ensureExplicitCapacity()方法
//判断是否需要扩容
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
//调用grow()方法进行扩容,调用此方法代表已经开始扩容了
grow(minCapacity);
}
我们来仔细分析一下

  1. 当我们要add进第一个元素到ArrayList时,elementData.length为0(因为还是一个空的list,里面还没有数据,所以没有进行扩容,默认扩容10),因为执行了ensureCapacityInternal()方法,所以minCapacity此时为10。此时,minCapacity - elemetData.length > 0(minCapacity=10,elemetData.length=0)成立,所以会进入==grow(minCapacity)==方法。
  2. 当add第2个元素时,minCapacity为2,此时elementData.length(容量)在添加第一个元素后扩容成10了。此时,minCapacity - elementData.length > 0不成立,所以不会进入(执行)==grow(minCapacity)==方法。
  3. 添加第3、4…到第10个元素时,依然不会执行==grow()==方法,数组容量都为10。
    知道添加第11个元素,minCapacity(为11)比elementData.length(为10)要大。进行grow方法进行扩容
  4. grow方法
    private void grow(int minCapacity) {
    // oldCapacity为旧容量,newCapacity为新容量
    int oldCapacity = elementData.length;//(0,10,15)
    //将oldCapacity右移一位,其效果相当于oldCapacity/2;
    // 我们知道位运算的速度远远快于整除运算,整句运算式的结果就是将新容量更新为旧容量的1.5倍
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    // 然后检查新容量是否大于最小需要容量,若还是小于最小需要容量,那么久把最小需要容量当作数组的新容量
    if (newCapacity - minCapacity < 0)
     newCapacity = minCapacity;
    
    //判断新容量是否大于集合的最大容量(一般大不了)
    if (newCapacity - MAX_ARRAY_SIZE > 0)
     newCapacity = hugeCapacity(minCapacity);
    
    // 给elementData从新赋值(10,15)
    elementData = Arrays.copyOf(elementData, newCapacity);
    }
    int newCapacity = oldCapacity + (oldCapacity >> 1),所以 ArrayList 每次扩容之后容量都会变为原来的 1.5 倍!
    “>>”(移位运算符):>>1 右移一位相当于除2,右移n位相当于除以 2 的 n 次方。这里 oldCapacity 明显右移了1位所以相当于oldCapacity /2。对于大数据的2进制运算,位移运算符比那些普通运算符的运算要快很多,因为程序仅仅移动一下而已,不去计算,这样提高了效率,节省了资源
    通过例子探究一下grow()方法
    ● 当add第一个元素时,oldCapacity为0,经比较后第一个if判断成立,newCapacity = minCapacity(为10)。但是第二个if判断不会成立,即newCapacity不比MAX_ARRAY_SIZE大,则不会进入hugeCapacity方法。数组容量为10,add方法中return true,size增为1。
    ● 当add第11个元素进入grow方法时,newCapacity为15,比minCapacity(为11)大,第一个if判断不成立。新容量没有大于数组最大size,不会进入hugeCapacity方法。数组容量扩为15,add方法中rerurn,true,size增为11。
    ● 以此类推…
    这里补充一点比较重要,但是容易被忽视掉的知识点:
    ● java中的length属性是针对数组说的,比如说你声明了一个数组,想知道这个数组的长度则用到了length这个属性。
    ● java中的length() 方法是针对字符串说的,如果想看这个字符串的长度则用到 length() 这个方法。
    ● java中的size() 方法是针对泛型集合说的,如果想看这个泛型有多少元素,就调用此方法类查看!
相关文章
CAP和Base理论
CAP理论指出:分布式系统中,分区容错性(P)不可避免,网络故障时需在一致性(C)和可用性(A)间权衡。BASE理论提供解决思路:基本可用、软状态、最终一致性,通过牺牲强一致性和部分可用性,保障系统整体可用与最终数据一致,适用于高并发分布式场景。(238字)
|
2月前
|
人工智能 安全 数据可视化
面向业务落地的AI产品评测体系设计与平台实现
在AI技术驱动下,淘宝闪购推进AI应用落地,覆盖数字人、数据分析、多模态创作与搜推AI化四大场景。面对研发模式变革与Agent链路复杂性,构建“评什么、怎么评、如何度量”的评测体系,打造端到端质量保障平台,并规划多模态评测、可视化标注与插件市场,支撑业务持续创新。
585 38
|
2月前
|
弹性计算 Kubernetes 安全
已上线!云监控 2.0 面向实体的全链路日志审计与风险溯源
在云端,一次 API 调用背后可能隐藏着一场数据泄露;一个异常进程背后,或许是 AK 泄露引发的链式攻击。传统日志“看得见却看不懂”,而云监控 2.0 日志审计通过 UModel 实体建模,将分散在 ACS、K8s、主机各层的日志自动串联。
266 59
|
2月前
|
存储 人工智能 Cloud Native
加入我们,一起定义「Data x AI」的未来
我们在杭州、上海开放岗位。如果你准备好了,请加入我们,一起建造 AI 时代最重要的数据基础设施。
176 24
|
2月前
|
机器学习/深度学习 人工智能 安全
2025 智能体工程现状
全面分析 AI 智能体在企业中的采用现状、挑战与趋势。
314 26
|
2月前
|
人工智能 安全 数据可视化
面向业务落地的AI产品评测体系设计与平台实现
在AI技术驱动下,淘宝闪购推进大模型应用落地,构建覆盖“评什么、怎么评、如何度量”的全链路评测体系。面对研发模式变革与Agent复杂性挑战,平台以端到端评测为主、分层测评为辅,打造可回放环境、多裁判机制及变更分级策略,实现质量与效率平衡。已支撑10+部门、90+AI产品,沉淀千余评测集,问题解决率超80%。未来将拓展多模态评测、可视化标注与插件市场,推动评测生态化发展。
什么是幂等
幂等性指操作执行一次或多次结果一致。读操作(如HTTP GET)不改变数据,天然幂等;写操作(如POST、PUT、DELETE)可能改变状态,需额外机制保障幂等。
|
3月前
|
人工智能 运维 Serverless
从 Transform 到 Transformer,用 EventBridge 与百炼构建实时智能的 ETL 数据管道
作为数据处理领域的经典模式,ETL(Extract-Transform-Load)通过提取、转换、加载三个步骤,高效地处理着各类结构化数据。然而,面对 AI 时代海量、异构、实时的“数据洪流”,传统 ETL 链路,尤其是其核心的转换(Transform)环节,正面临严峻挑战。本文将从一个初级开发者也能理解和上手的视角,探讨 AI 时代的数据处理新范式:如何利用基于 Transformer 架构的大语言模型(LLM)重塑传统数据处理中的转换(Transform)环节,并结合事件驱动架构(Event-Driven Architecture, EDA),为 AI 数据处理链路“注入实时智能”。
282 30
|
2月前
|
机器学习/深度学习 人工智能 算法
让AI真正读懂长文本的秘密武器
通义实验室推出QwenLong-L1.5,基于Qwen3-30B-A3B打造的长文本推理专家。通过高质量多跳数据合成、稳定强化学习算法与突破窗口限制的记忆框架,系统性解决长文本“学不好、用不了”难题,在多跳推理、超长上下文等任务中媲美GPT-5与Gemini。

热门文章

最新文章