ArrayList扩容机制

简介: 本文深入解析Java中ArrayList的add及扩容机制。通过源码分析,详解add方法如何调用ensureCapacityInternal、ensureExplicitCapacity及grow方法实现动态扩容,揭示其容量每次增长1.5倍的核心逻辑,并区分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() 方法是针对泛型集合说的,如果想看这个泛型有多少元素,就调用此方法类查看!
相关文章
|
3月前
|
前端开发 数据可视化
什么是低代码
该界面为低代码平台,支持通过拖拽方式快速生成前端表单页面,提升开发效率。包含可视化操作与组件配置,适用于快速搭建业务表单。参考文档详见附件。
|
5月前
|
人工智能 自然语言处理 数据安全/隐私保护
AI生成的文本:如何识破机器的“笔迹”?
AI生成的文本:如何识破机器的“笔迹”?
893 85
|
Web App开发 移动开发 JavaScript
JS - 微信浏览器(H5)语音录音插件(Recorder H5)
JS - 微信浏览器(H5)语音录音插件(Recorder H5)
3392 0
|
4月前
|
监控 数据挖掘 API
淘宝天猫商品详情API全攻略
淘宝天猫商品详情API是淘宝开放平台的核心接口,支持通过商品ID获取标题、价格、库存、SKU等全维度信息,采用RESTful设计,实时高效,适用于比价系统、库存监控、智能选品等电商应用开发与数据分析场景。
|
3月前
|
Kubernetes 网络协议 容器
【k8s-1.34.2安装部署】七.coredns-v1.13.1安装
本章介绍如何安装并验证coredns-v1.13.1。下载coredns.yaml.base文件,替换镜像地址、DNS域、内存限制及服务IP,应用配置后通过svc和pod验证CoreDNS解析功能是否正常。
358 13
|
4月前
|
存储 Web App开发 前端开发
新手如何建站.新手建站的全流程
建站是通过整合域名、服务器等要素搭建可访问数字平台的过程,分自助建站、CMS系统和代码开发三类工具。核心流程包括需求规划、域名注册(实名认证)、服务器配置(国内需ICP备案),搭建后填充内容并测试优化,解析域名上线,做好后续维护。
497 10
|
3月前
|
安全 Java 开发工具
整合SpringSecurity
本文介绍了Spring Security与Spring Boot的整合步骤:引入依赖、启动验证及登录测试。通过日志变化和自动跳转至login页面验证集成成功,使用默认用户名user和控制台生成的动态密码登录后,可访问受保护资源。完整代码见GitHub仓库Day01分支。
|
7月前
|
存储 新零售 安全
阿里云盘企业版收费标准、功能支持、存储配置及用户数全解析
阿里云盘企业版提供高性价比存储方案,500GB仅需169元/年,支持协同办公、权限管理、智能文件管理、多重安全防护及卓越性能,适用于多行业企业高效办公。
1176 0
|
消息中间件 人工智能 安全
秒级灾备恢复:Kafka 2025 AI自愈集群下载及跨云Topic迁移终极教程
Apache Kafka 2025作为企业级实时数据中枢,实现五大革新:量子安全传输(CRYSTALS-Kyber抗量子加密算法)、联邦学习总线(支持TensorFlow Federated/Horizontal FL框架)、AI自愈集群(MTTR缩短至30秒内)、多模态数据处理(原生支持视频流、3D点云等)和跨云弹性扩展(AWS/GCP/Azure间自动迁移)。平台采用混合云基础设施矩阵与软件依赖拓扑设计,提供智能部署架构。安装流程涵盖抗量子安装包获取、量子密钥配置及联邦学习总线设置。

热门文章

最新文章