ArrayList扩容机制源码分析
ArrayList的构造函数分析ArrayList有三个主要的构造函数ArrayList(): 无参构造函数以无参数构造方法创建ArrayList时实际上初始化赋值的是一个空数组。当真正对数组进行添加元素操作时才真正分配容量。即向数组中添加第一个元素时数组容量扩为 10。ArrayList(int initialCapacity): 通过指定初始容量来创建一个ArrayList。ArrayList(Collection? extends E c): 通过另一个集合来初始化ArrayList容量初始为c.size()。/** * 默认初始容量大小 */ private static final int DEFAULT_CAPACITY 10; private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA {}; /** * 默认构造函数使用初始容量10构造一个空列表(无参数构造) */ public ArrayList() { this.elementData DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } /** * 带初始容量参数的构造函数。用户自己指定容量 */ public ArrayList(int initialCapacity) { if (initialCapacity 0) {//初始容量大于0 //创建initialCapacity大小的数组 this.elementData new Object[initialCapacity]; } else if (initialCapacity 0) {//初始容量等于0 //创建空数组 this.elementData EMPTY_ELEMENTDATA; } else {//初始容量小于0抛出异常 throw new IllegalArgumentException(Illegal Capacity: initialCapacity); } } /** *构造包含指定collection元素的列表这些元素利用该集合的迭代器按顺序返回 *如果指定的集合为nullthrows NullPointerException。 */ public ArrayList(Collection? extends E c) { elementData c.toArray(); if ((size elementData.length) ! 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() ! Object[].class) elementData Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData EMPTY_ELEMENTDATA; } }add()方法及其扩容逻辑ArrayList的add()方法会将元素添加到内部数组。如果数组容量不够就会触发扩容机制。/** * 将指定的元素追加到此列表的末尾。 */ public boolean add(E e) { // 加元素之前先调用ensureCapacityInternal方法 ensureCapacityInternal(size 1); // Increments modCount!! // 这里看到ArrayList添加元素的实质就相当于为数组赋值 elementData[size] e; return true; }ensureCapacityInternal(size 1)这是扩容机制的核心。ensureCapacityInternal()首先检查当前数组的容量是否足够存放新元素。如果不够就会调用grow()方法进行扩容。elementData[size] e在扩容之后元素会被添加到elementData数组中size会增加表示当前ArrayList包含的元素数量。ensureCapacityInternal方法的源码如下// 确保内部容量达到指定的最小容量。 private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); }// 根据给定的最小容量和当前数组元素来计算所需容量。 private static int calculateCapacity(Object[] elementData, int minCapacity) { // 如果当前数组元素为空数组初始情况返回默认容量和最小容量中的较大值作为所需容量 if (elementData DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } // 否则直接返回最小容量 return minCapacity; }//判断是否需要扩容 private void ensureExplicitCapacity(int minCapacity) { modCount; //判断当前数组容量是否足以存储minCapacity个元素 if (minCapacity - elementData.length 0) //调用grow方法进行扩容 grow(minCapacity); }grow()方法分析grow()方法用于扩容它会创建一个新数组并复制旧数组中的数据/** * 要分配的最大数组大小 */ private static final int MAX_ARRAY_SIZE Integer.MAX_VALUE - 8; /** * ArrayList扩容的核心方法。 */ private void grow(int minCapacity) { // oldCapacity为旧容量newCapacity为新容量 int oldCapacity elementData.length; // 将oldCapacity 右移一位其效果相当于oldCapacity /2 // 我们知道位运算的速度远远快于整除运算整句运算式的结果就是将新容量更新为旧容量的1.5倍 int newCapacity oldCapacity (oldCapacity 1); // 然后检查新容量是否大于最小需要容量若还是小于最小需要容量那么就把最小需要容量当作数组的新容量 if (newCapacity - minCapacity 0) newCapacity minCapacity; // 如果新容量大于 MAX_ARRAY_SIZE,进入(执行) hugeCapacity() 方法来比较 minCapacity 和 MAX_ARRAY_SIZE // 如果minCapacity大于最大容量则新容量则为Integer.MAX_VALUE否则新容量大小则为 MAX_ARRAY_SIZE 即为 Integer.MAX_VALUE - 8。 if (newCapacity - MAX_ARRAY_SIZE 0) newCapacity hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData Arrays.copyOf(elementData, newCapacity); }关键步骤通过oldCapacity 1来增加1.5倍容量。如果newCapacity大于Integer.MAX_VALUE则会调用hugeCapacity()来防止溢出。hugeCapacity()方法分析private static int hugeCapacity(int minCapacity) { if (minCapacity 0) // overflow throw new OutOfMemoryError(); // 对minCapacity和MAX_ARRAY_SIZE进行比较 // 若minCapacity大将Integer.MAX_VALUE作为新数组的大小 // 若MAX_ARRAY_SIZE大将MAX_ARRAY_SIZE作为新数组的大小 // MAX_ARRAY_SIZE Integer.MAX_VALUE - 8; return (minCapacity MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }hugeCapacity()方法比较minCapacity最小需要容量和MAX_ARRAY_SIZE如果minCapacity大于最大容量则新容量则为Integer.MAX_VALUE否则新容量大小则为MAX_ARRAY_SIZE即为Integer.MAX_VALUE - 8。ArrayList扩容机制总结ArrayList是Java中的一个动态数组实现其扩容机制是为了应对在添加元素时数组容量不足的情况。扩容的主要目的是避免频繁的内存分配和拷贝提高性能。以下是ArrayList扩容机制的核心概念和步骤1.初始容量默认情况下ArrayList使用一个容量为10的内部数组来存储元素使用无参构造器ArrayList()创建时先创建一个空数组第一次添加元素是使用默认大小10.通过ArrayList(int initialCapacity)构造函数可以设置自定义的初始容量这样在构造时就可以避免不必要的扩容。2.add()方法add(E e)方法是将元素添加到ArrayList中的核心方法。每当调用add()方法时会执行以下步骤检查容量首先会通过ensureCapacityInternal()方法检查当前容量是否足够容纳新元素。扩容如果当前容量不够则会调用grow()方法进行扩容。添加元素将元素添加到elementData数组中并更新size。3.扩容过程当ArrayList的容量不足时ensureCapacityInternal()会调用grow()方法进行扩容。grow()方法扩容规则grow(int minCapacity)方法的作用是动态扩展内部数组的容量。扩容的基本策略是将当前数组的容量增大1.5倍即newCapacity oldCapacity (oldCapacity 1)这种增量是为了平衡内存利用率和性能。如果扩容后的容量小于minCapacity则直接将容量设置为minCapacity。如果扩容后的容量大于Integer.MAX_VALUE则会采用hugeCapacity()来避免溢出。4.扩容时的数组复制扩容过程中grow()方法会创建一个新的数组并使用Arrays.copyOf()方法将原数组中的元素复制到新的数组中。这种数组的复制是一个相对昂贵的操作因此扩容的次数尽量应保持在最低。5.扩容的影响每次扩容都会导致内存的重新分配和元素的复制这可能会影响性能尤其是在大量元素被频繁添加的场景下。为了减少扩容次数可以通过设置合适的初始容量来避免过多的扩容操作。

相关新闻

永磁同步电机:直接转矩控制、电流预测模型、无位置传感、滑模控制

永磁同步电机:直接转矩控制、电流预测模型、无位置传感、滑模控制

永磁同步电机直接转矩控制,电流预测模型,无位置传感,滑模控制。永磁同步电机的直接转矩控制(DTC)就像给电机装了个"直觉系统",不需要复杂的坐标变换就能直接怼转矩和磁链。但玩过的人都知道&…

2026/7/4 17:36:04 阅读更多 →
矽塔科技 SA2626L 1.5-7.5V/2.6A 双通道 H 桥电机驱动器 SOP16 技术解析

矽塔科技 SA2626L 1.5-7.5V/2.6A 双通道 H 桥电机驱动器 SOP16 技术解析

在电子门锁、机器人以及快消品等需要较高功率驱动的应用中,需要一款能在宽电压范围内提供强大电流的双通道电机驱动器。SA2626L 是一款专为双通道直流电机或单步进电机设计的 H 桥驱动芯片,采用 SOP16 封装,工作电压为 1.5V 至 7.5V&#xff…

2026/7/7 2:45:00 阅读更多 →
phpstorm 设置 vmoptions后生成的在什么具体位置

phpstorm 设置 vmoptions后生成的在什么具体位置

phpstorm 设置 vmoptions后生成的在什么具体位置 C:\Users\Administrator.PhpStorm2019.3\config\phpstorm64.exe.vmoptions 您提到的 C:\Users\Administrator.PhpStorm2019.3\config\phpstorm64.exe.vmoptions 确实是 PhpStorm 2019.3 的 JVM 选项配置文件。这个文件用于设置启…

2026/7/3 16:12:51 阅读更多 →

最新新闻

Stable Diffusion 3 与 Midjourney V6 对比评测:5个商业设计场景下的出图效率与成本分析

Stable Diffusion 3 与 Midjourney V6 对比评测:5个商业设计场景下的出图效率与成本分析

Stable Diffusion 3 与 Midjourney V6 商业设计实战评测:5大场景下的效率与成本拆解当电商设计师Lisa凌晨三点还在反复修改产品主图时,她需要的不是又一个AI绘画工具列表,而是能直接提升商业出图效率的实战解决方案。这正是我们耗时两个月深度…

2026/7/7 10:28:46 阅读更多 →
高效免费GPU内存检测:3个实用场景教你快速排查显卡硬件问题

高效免费GPU内存检测:3个实用场景教你快速排查显卡硬件问题

高效免费GPU内存检测:3个实用场景教你快速排查显卡硬件问题 【免费下载链接】memtestCL OpenCL memory tester for GPUs 项目地址: https://gitcode.com/gh_mirrors/me/memtestCL 你是否遇到过显卡运行不稳定、游戏频繁崩溃或计算任务异常中断的问题&#xf…

2026/7/7 10:26:46 阅读更多 →
星穹铁道自动化助手:告别重复劳动的游戏管家

星穹铁道自动化助手:告别重复劳动的游戏管家

星穹铁道自动化助手:告别重复劳动的游戏管家 【免费下载链接】StarRailAssistant 崩坏:星穹铁道自动化 | 崩坏:星穹铁道自动锄大地 | 崩坏:星穹铁道锄大地 | 自动锄大地 | 基于模拟按键 项目地址: https://gitcode.com/gh_mirro…

2026/7/7 10:24:45 阅读更多 →
如何在Windows上快速安装苹果USB驱动:终极解决方案指南

如何在Windows上快速安装苹果USB驱动:终极解决方案指南

如何在Windows上快速安装苹果USB驱动:终极解决方案指南 【免费下载链接】Apple-Mobile-Drivers-Installer Powershell script to easily install Apple USB and Mobile Device Ethernet (USB Tethering) drivers on Windows! 项目地址: https://gitcode.com/gh_mi…

2026/7/7 10:22:44 阅读更多 →
WSEN-ISDS与MK64FN1M0VDC12的IMU运动跟踪方案

WSEN-ISDS与MK64FN1M0VDC12的IMU运动跟踪方案

1. 项目背景与硬件选型解析在工业自动化、无人机控制和机器人导航等领域,精确的空间运动感知是核心需求。WSEN-ISDS(型号2536030320001)作为一款集成三轴加速度计和陀螺仪的6自由度惯性测量单元(IMU),配合MK64FN1M0VDC12微控制器&…

2026/7/7 10:16:42 阅读更多 →
GraphSAGE 2.0 PyTorch 实战:5步实现归纳式学习,处理动态图新增节点

GraphSAGE 2.0 PyTorch 实战:5步实现归纳式学习,处理动态图新增节点

GraphSAGE 2.0 PyTorch 实战:5步实现动态图节点归纳学习1. 动态图与归纳式学习的工程挑战社交网络每秒钟新增的用户、电商平台实时上架的商品、物联网设备动态加入的节点——这些场景都在描述一个共同的技术挑战:**如何让图神经网络处理持续变化的图结构…

2026/7/7 10:16:42 阅读更多 →

日新闻

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

图片浏览是移动应用中最高频的场景之一。从社交应用的照片流到电商平台的商品图集,从旅游应用的景点相册到摄影作品展示——用户对图片浏览的体验要求不断提高:流畅的切换动画、直观的缩略图导航、便捷的收藏操作、自动播放模式。HarmonyOS NEXT ArkUI 虽…

2026/7/7 0:05:16 阅读更多 →
24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V稳压芯片完整选型指南 PW8600 PW75XX PW2815 PW2312B LDODC/DC全方案 一、24V稳压方案概述 24V直流电源在工业自动化、门禁系统、电梯控制、汽车电子、LED驱动、监控设备等场景中应用极广,是最常见的中压直流母线电压。要将24V母线稳定降压至下游MCU、传感器…

2026/7/7 0:05:16 阅读更多 →
RAG+知识图谱混合检索与Graph RAG核心对比

RAG+知识图谱混合检索与Graph RAG核心对比

做企业RAG落地的团队,往往容易卡在一容易踩坑的选型难题: 当需求单纯靠向量RAG搞不定、单纯靠知识图谱也搞不定,必须同时依赖「文本语义理解 实体关系推理」时,到底是做「向量图谱混合检索」就够了,还是必须上「Grap…

2026/7/7 0:07:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻