首页 > 编程语言 >超详细的ArrayList扩容过程(配合源码详解)

超详细的ArrayList扩容过程(配合源码详解)

时间:2024-11-19 20:31:42浏览次数:1  
标签:int MAX ArrayList elementData newCapacity minCapacity 数组 源码 详解

首先,在调用add方法的时候 ,会去调用 ensureCapacityInternal 方法,传入一个参数 minCapacity 大小是size + 1,也就是现在我们需要的数组的最小的大小。
在ensureCapacityInternal 方法中,先判断一下elementdata是不是初始空数组
是的话就把minCapacity变更为默认容量 也就是10, 和传进来的minCapacity的最大值
之后调用 ensureExplicitCapacity 方法,把现在的minCapacity传进去

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    ensureExplicitCapacity(minCapacity);
}

第二步:
在这个ensureExplicitCapacity 方法中,会去判断一下传进来的minCapacity和当前elementdata的大小,如果需要的这个最小容量已经超过了当前数组的长度,就会去调用grow方法,也就是扩容的核心方法,并且把这个minCapacity传进去

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

第三步:
进入grow方法后,先去获取现在的elementdata的长度,并且先行扩容到1.5倍(这个>>1是位运算)。扩容后的容量记为 newCapacity ,用这个newCapacity 去和minCapacity也就是我们需要的最小的大小进行比较,还是达不到的话就让newCapacity=minCapacity。接着还要处理一下当前的newCapacity超过MAX_ARRAY_SIZE,也就是ArrayList允许的数组最大值的情况(一般是Integer.MAX_VALUE - 8)。调用hugeCapacity来进行处理,小于0的话就抛异常,超过最大值了就取最大值。最后调用Arrays.copyOf()方法。

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1); // 扩容到原来的 1.5 倍
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity; // 若新容量仍不足,则取所需的最小容量
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity); // 检查是否超过最大允许大小
    elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError(); // 超出 int 最大值时抛出异常
    return (minCapacity > MAX_ARRAY_SIZE) ?
           Integer.MAX_VALUE : // 如果实际需求超大,则直接取 Integer.MAX_VALUE
           MAX_ARRAY_SIZE;     // 否则取最大允许的数组大小
}

最后在这个Arrays.copyOf()方法中会创建一个新的数组,大小就是我们上一步得到并且传入的newCapacity。接着把旧数组中的元素拷贝到新数组中。

public static <T> T[] copyOf(T[] original, int newLength) {
    T[] copy = (T[]) Array.newInstance(original.getClass().getComponentType(), newLength);
    System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
    return copy;
}

标签:int,MAX,ArrayList,elementData,newCapacity,minCapacity,数组,源码,详解
From: https://www.cnblogs.com/nicebaoke/p/18555533

相关文章

  • flask框架儿童认知图文辅助系统(毕设源码+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景关于儿童认知辅助教育的研究,现有研究主要以传统教学方式为主,如单纯的课本知识传授或简单的动画演示等。专门针对将图文结合并融入学生......
  • eevdf 内核调度器 源码分析 (1)
    eevdf内核调度器源码分析(1)简介vruntime的变化到底什么是Eligible?eligibletime和deadlinetime结语简介本文会从源码角度,简单分析eevdf(EarliestEligibleVirtualDeadlineFirst)内核调度器。阅读本文需要一定cfs调度器的基础知识。vruntime的变化在cfs中,有一......
  • 基于SpringBoot+Vue的旅游网站管理系统设计与实现毕设(文档+源码)
    目录一、项目介绍二、开发环境三、功能介绍四、核心代码五、效果图六、源码获取:         大家好呀,我是一个混迹在java圈的码农。今天要和大家分享的是一款基于SpringBoot+Vue的旅游网站管理系统,项目源码请点击文章末尾联系我哦~目前有各类成品毕设JavaWeb......
  • 基于SpringBoot+Vue的论坛管理系统设计与实现毕设(文档+源码)
    目录一、项目介绍二、开发环境三、功能介绍四、核心代码五、效果图六、源码获取:         大家好呀,我是一个混迹在java圈的码农。今天要和大家分享的是一款基于SpringBoot+Vue的论坛管理系统,项目源码请点击文章末尾联系我哦~目前有各类成品毕设JavaWeb SSM......
  • FPGA 14 ,硬件开发板分类详解,FPGA开发板与普通开发板烧录的区别
    目录前言在嵌入式系统开发中,硬件开发板是工程师常用的工具之一。不同类型的开发板有不同的特点和用途,其中最常见的两大类是普通开发板和FPGA开发板。这里分享记录,这两类开发板的分类,并深入探讨它们在烧录过程中的具体区别,帮助我们更好地理解和选择适合自己的开发板。一. 开......
  • 事务的详解
    什么是事务?事务是逻辑上的一组操作,要么都执行,要么都不执行。另外,需要格外注意的是:事务能否生效数据库引擎是否支持事务是关键。比如常用的MySQL数据库默认使用支持事务的innodb引擎。但是,如果把数据库引擎变为myisam,那么程序也就不再支持事务了!事务最经典也经常被拿出......
  • 计算机毕设源码 python-基于flask在线考试系统
    标题:python-基于flask在线考试系统设计一个基于Flask框架的在线考试系统,需要考虑考生、教师和管理员的不同需求,确保系统的易用性、公平性和安全性。以下是一个典型的在线考试系统的主要功能模块:1.用户注册与登录•注册:用户可以通过手机号码、邮箱或社交账号注册。•登录:用......
  • 【Python】30个Python爬虫的实战项目!!!(附源码)
    Python爬虫是数据采集自动化的利器。本文精选了30个实用的Python爬虫项目,从基础到进阶,每个项目都配有完整源码和详细讲解。通过这些项目的实战,可以全面掌握网页数据抓取、反爬处理、并发下载等核心技能。一、环境准备在开始爬虫项目前,需要安装以下Python库:......
  • 从0开始学习Linux——Shell编程详解【01】
    期目录:从0开始学习Linux——简介&安装从0开始学习Linux——搭建属于自己的Linux虚拟机从0开始学习Linux——文本编辑器从0开始学习Linux——Yum工具从0开始学习Linux——远程连接工具从0开始学习Linux——文件目录从0开始学习Linux——网络配置从0开始学习Linux——防......
  • WebSocket的应用:前后端详解与使用
    一、简介WebSocket是一种网络通信协议,它提供了在单个TCP连接上进行全双工通信的功能。在下面这个聊天应用示例中,WebSocket被用于实现实时的聊天功能,包括用户之间的消息发送、接收,用户状态管理以及其他相关的交互操作,为用户带来流畅的聊天体验。二、后端实现(一)模块引入与......