本文将系统地介绍 Java 中 ArrayList 的扩容机制,包括其初始容量的设置、触发扩容的时机、容量增长算法、扩容的详细流程以及性能优化建议,帮助读者从源码层面深入理解这一关键特性,并在实际开发中合理预分配容量以提升性能。

一、ArrayList 简介

ArrayList 底层由一个可变长度的数组 elementData 支撑,可在运行时动态调整大小,属于顺序表的具体实现,具有随机访问速度快、增删效率相对较低、非线程安全的特点

二、初始化与构造

1. 无参构造器

  • 调用 new ArrayList<>() 时,elementData 被赋值为一个空数组常量 DEFAULTCAPACITY_EMPTY_ELEMENTDATA,此时容量为 0
  • 当第一次添加元素时,ensureCapacityInternal(1) 将最小容量 minCapacity 与默认容量 DEFAULT_CAPACITY = 10 比较,最终分配容量为 10

2. 指定初始容量构造器

  • 使用 new ArrayList<>(initialCapacity) 会直接分配长度为 initialCapacity 的底层数组,跳过默认容量提升逻辑,可避免第一次添加元素时的数组复制

三、扩容触发时机

  • 每次调用 add(E e) 时,都会执行 ensureExplicitCapacity(size + 1),若 size + 1 超出当前数组长度则触发扩容
  • ensureCapacityInternal 会仅在 minCapacity - oldCapacity > 0 时才进行扩容,以避免多余的复制操作

四、扩容算法

  • 自 JDK 8 起,容量增长公式为:

    java复制编辑
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    

    即在旧容量基础上增加约 50%。

  • 在 JDK 6 及更早版本,采用 (oldCapacity * 3) / 2 + 1 的方式,效果相似。

  • 若计算出的 newCapacity 小于 minCapacity,则直接使用 minCapacity;若超过 Integer.MAX_VALUE,则调用 hugeCapacity 调整至可用最大值或抛出 OutOfMemoryError,以防止整数溢出。

五、扩容流程详解

  1. 计算最小需求

    • minCapacity = size + 1
  2. 空数组检测

    • 若底层数组为 DEFAULTCAPACITY_EMPTY_ELEMENTDATA,则将 minCapacityDEFAULT_CAPACITY(10)比较,取较大者。
  3. 调用 grow(minCapacity)

    • 读取 oldCapacity = elementData.length
    • 按扩容算法计算新容量 newCapacity = oldCapacity + (oldCapacity >> 1)
    • newCapacity < minCapacity,则 newCapacity = minCapacity
    • newCapacity 超出最大阈值,则经 hugeCapacity(minCapacity) 处理。
  4. 数组复制

    • 使用 Arrays.copyOf(elementData, newCapacity) 创建并替换底层数组,实现元素迁移

    • 迭代器快速失败支持

    • 扩容时会自增 modCount,保证在多线程环境下对并发修改的检测与抛出 ConcurrentModificationException

六、性能优化建议

  • 预分配容量:若能预计元素数量,建议使用 new ArrayList<>(expectedSize) 或提前调用 ensureCapacity(expectedSize),可显著减少扩容次数及数组复制开销 。
  • 扩容策略权衡:1.5 倍的增长因子在性能(降低复制频次)与内存利用率(避免过度浪费)之间取得平衡,是常见动态数组设计策略。
  • 批量操作:对于大量元素的插入,可先将所有元素聚合至临时数组或使用 addAll(Collection),以减少多次单个元素添加带来的重复扩容开销.。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/78800.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/78800.shtml
英文地址,请注明出处:http://en.pswp.cn/web/78800.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【网络服务器】——回声服务器(echo)

作用 实现回声服务器的客户端/服务器程序&#xff0c;客户端通过网络连接到服务器&#xff0c;并发送任意一串英文信息&#xff0c;服务器端接收信息后&#xff0c;执行数据处理函数&#xff1a;将每个字符转换为大写并回送给客户端显示。 客户端&#xff1a;发送字符信息 服…

智能学习空间的范式革新:基于AI驱动的自习室系统架构与应用研究

摘要 在 “互联网 + 教育” 深度融合的背景下,传统自习室面临个性化服务缺失、学习效率低下等瓶颈。本文提出一种基于人工智能技术的 AI 自习室系统架构,通过构建多模态数据感知、个性化学习引擎及智能环境调控模块,实现学习过程的精准化、智能化与沉浸式体验。研究结合计算…

HTML01:HTML基本结构

HTML基本结构 <html> <head><meta charset"UTF-8"><title>我的第一个网页</title> </head> <body>我的第一个网页 </body> </html><body、</body等成对的标签&#xff0c;分别叫开发标签和闭合标签单独…

Spring Boot 实现多种来源的 Zip 多层目录打包下载(本地文件HTTP混合)

需要将一批文件&#xff08;可能分布在不同目录、不同来源&#xff09;打包成Zip格式&#xff0c;按目录结构导出给用户下载。 1. 核心思路 支持将本地服务器上的文件&#xff08;如/data/upload/xxx.jpg&#xff09;打包进Zip&#xff0c;保持原有目录结构。支持通过HTTP下载…

【Elasticsearch】在kibana中能获取已创建的api keys吗?

在 Kibana 中&#xff0c;目前没有直接的界面功能可以列出或查看已创建的 API 密钥&#xff08;API keys&#xff09;。API 密钥的管理和查看主要通过 Elasticsearch 的 REST API 来完成&#xff0c;而不是通过 Kibana 的管理界面。 在 Kibana 中使用 Dev Tools 查看 API 密钥…

公司项目架构搭建者

公司项目架构搭建者分析 项目架构搭建的核心角色 #mermaid-svg-FzOOhBwW3tctx2AR {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-FzOOhBwW3tctx2AR .error-icon{fill:#552222;}#mermaid-svg-FzOOhBwW3tctx2AR .err…

《技术驯化情感:AI伴侣、监控与伦理框架的重构挑战》

技术渗透与情感异化机制 情感计算技术正通过多种核心算法和数据处理方法深入人类生活&#xff0c;其在重构人类情感关系的同时也潜藏情感异化风险。本节从生物特征捕捉、行为模式诱导和认知框架重塑三方面解析情感计算的技术机理&#xff0c;并探讨其导致的情感依赖现象。 生物…

32单片机——独立看门狗

1、IWDG的简介 IWDG&#xff1a;Independent watchdog&#xff0c;即独立看门狗 独立看门狗本质上是一个定时器&#xff0c;该定时器是一个12位的递减计数器&#xff0c;当计数器的值减到0的时候&#xff0c;就会产生一个复位信号 如果在计数没减到0之前&#xff0c;重置计数器…

[计算机网络]数据链路层

408考纲(数链层部分): 0 概论&#xff1a;数据链路层都干什么事&#xff0c;提供啥功能 比物理层再高一层就是数据链路层&#xff0c;咱们上一篇讲物理层&#xff0c;物理层直接接触传输介质&#xff0c;现在数据链路层是使用物理层的传输服务&#xff0c;然后实现更多的功能。…

OpenAI大变革!继续与微软等,以非营利模式冲击AGI

今天凌晨2点&#xff0c;OpenAI宣布&#xff0c;将继续由非营利组织控制&#xff1b;现有的营利性实体将转变为一家公共利益公司&#xff1b;非营利组织将控制该公共利益公司&#xff0c;并成为其重要的持股方。 这也就是说OpenAI曾在去年提到的由非营利性转变成营利性公司&am…

库存怎么管?怎样才能做到有效的库存管理?

说到库存管理&#xff0c;估计大多数老板和管理者都有过“烦心事”。一方面&#xff0c;库存过多&#xff0c;货物堆积如山&#xff0c;堆在仓库里也不动&#xff0c;结果占地方还占用资金&#xff1b;另一方面&#xff0c;又有可能遇到客户急着要货&#xff0c;可是库存却紧张…

Kotlin-空值和空类型

变量除了能引用一个具体的值之外,还有一种特殊的值,那就是 null, 它代表空值, 也就是不引用任何对象 在Kotlin中, 对空值的处理是非常严格的,正常情况下,我们的变量是不能直接赋值为 null 的,否则无法编译通过, 这直接在编译阶段就避免了空指针问题 Kotlin中所有的类型默认都是…

[特殊字符]算法次元突破:螺旋矩阵的“能量解码术” vs 超立方体的“维度折叠指南”

&#x1f50d; 引言 如果科幻电影中的能量矩阵是算法的考题&#xff0c;你会用螺旋指针破解它的DNA吗&#xff1f; 如果《星际穿越》的五维空间变成编程题&#xff0c;你敢用动态规划丈量时间的褶皱吗&#xff1f; 今天&#xff0c;我们将化身算法世界的能量解…

高光谱相机赋能烟叶分选:精准、高效与智能化的新突破

烟草产业作为中国重要的经济支柱&#xff0c;烟叶分选的质量与效率直接影响行业效益。传统人工分选存在效率低、主观性强、标准难以统一等问题&#xff0c;而机器视觉技术受限于可见光波段&#xff0c;难以捕捉烟叶深层特征。深圳中达瑞和科技有限公司推出的高光谱相机解决方案…

矩阵求导常用公式解析:标量、向量与矩阵的导数计算

矩阵求导常用公式解析&#xff1a;标量、向量与矩阵的导数计算 矩阵求导常用公式解析&#xff1a;标量、向量与矩阵的导数计算矩阵求导的布局问题1. 分子布局 vs 分母布局对比表2. 布局冲突的典型场景分析3. 混合布局的兼容性处理 一、标量对向量求导1. 线性函数求导2. 二次型函…

NocoDB:开源的 Airtable 替代方案

NocoDB:开源的 Airtable 替代方案 什么是 NocoDB?NocoDB 的主要特点丰富的电子表格界面工作流自动化应用商店程序化访问NocoDB 的应用场景使用 Docker 部署 NocoDB1. 创建数据目录2. 运行 Docker 容器3. 访问 NocoDB注意事项总结什么是 NocoDB? NocoDB 是一款功能强大的开源…

全格式文档转 Markdown 工具,Docker 一键部署,支持 API 调用

以下是简要介绍&#xff1a; 这是一款可以快速将任意文档文件转markdown格式内容的工具&#xff0c;提供API转换接口&#xff0c;方便集成与应用原理就是利用libreoffice、pandoc文件转换工具&#xff0c;把所有文档类型的文件逐步转化&#xff0c;最终转成markdown格式的内容…

MATLAB绘制饼图(二维/三维)

在数据分析与展示领域&#xff0c;饼图是一种直观且高效的可视化工具&#xff0c;能够在瞬间传递各部分与整体的比例关系。今天&#xff0c;我将分享一段 MATLAB 绘制二维及三维饼图的代码&#xff0c;助你轻松将数据以饼图形式呈现于众人眼前。 无论是二维饼图的简洁明了&…

AI笔记-1

Halide Perovskites (HPs) 卤化物钙钛矿 卤化物钙钛矿&#xff08;HPs&#xff09;已被 公认为 光伏和发光器件 中最有前途的材料之一 在本观点中&#xff0c;我们将探讨钙钛矿的定义&#xff0c;主要聚焦于由 较重卤素&#xff08;Cl、Br和I&#xff09;组成的钙钛矿亚群&…

excel表数据导入数据库

前两天&#xff0c;有个两DB之间的数据导出导入的需求。对方提供的是excel表&#xff0c;我这边是mysql数据库&#xff0c;excel表第一行是字段名&#xff0c;之后的行是记录的值。 其实没有多复杂&#xff0c;我先将exel转成csv&#xff0c;结果mysql导入csv&#xff0c;第一行…