Java基础集合ArrayList扩容机制

简介: 本文详解ArrayList的add及扩容机制:添加元素时先调用ensureCapacityInternal(),首次扩容至10;通过grow()实现容量1.5倍增长(oldCapacity + (oldCapacity >> 1)),当元素数超当前容量时触发扩容。length为数组属性,length()为字符串方法,size()用于集合大小获取。

先来看Add方法
再来看看ensureCapacityInternal()方法,可以看到add()方法首先调用了ensureCapacityInternal(size+1)
当要add进第一个元素时,minCapacity为1,在Math.max()方法比较后,minCapacity为10
ensureExplicitCapacity()方法
Java
运行代码
复制代码
1
2
3
4
5
6
7
8
//判断是否需要扩容
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
//调用grow()方法进行扩容,调用此方法代表已经开始扩容了
grow(minCapacity);
}
我们来仔细分析一下
当我们要add进第一个元素到ArrayList时,elementData.length为0(因为还是一个空的list,里面还没有数据,所以没有进行扩容,默认扩容10),因为执行了ensureCapacityInternal()方法,所以minCapacity此时为10。此时,minCapacity - elemetData.length > 0(minCapacity=10,elemetData.length=0)成立,所以会进入==grow(minCapacity)==方法。
当add第2个元素时,minCapacity为2,此时elementData.length(容量)在添加第一个元素后扩容成10了。此时,minCapacity - elementData.length > 0不成立,所以不会进入(执行)==grow(minCapacity)==方法。
添加第3、4…到第10个元素时,依然不会执行==grow()==方法,数组容量都为10。
知道添加第11个元素,minCapacity(为11)比elementData.length(为10)要大。进行grow方法进行扩容
grow方法
Java
运行代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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() 方法是针对泛型集合说的,如果想看这个泛型有多少元素,就调用此方法类查看!

相关文章
|
2月前
|
缓存 开发工具 git
QLExpress使用及源码分析
QLExpress是阿里开源的轻量级规则引擎,支持通过注解与YAML配置实现业务逻辑解耦。基于AST语法树解析,提供上下文绑定、动态脚本执行与缓存机制,适用于复杂条件判断与计算场景,如BMI计算、用户规则校验等,具备高扩展性与易维护性。
|
2月前
|
Arthas 监控 Java
arthas 基础指令
Arthas简介:通过dashboard查看线程状态、CPU占用等;jad反编译类文件;thread分析线程堆栈及阻塞情况;watch监控方法执行耗时与参数;支持quit退出连接或stop彻底终止。适用于Java进程诊断,操作便捷,功能强大。(239字)
|
2月前
|
Arthas 监控 Java
arthas 安装
本教程介绍Arthas的安装与基础使用。需提前安装JDK并确保服务器有Java应用运行。下载arthas-boot.jar,上传Java应用(如Arthas-demo.jar),启动后通过`java -jar arthas-boot.jar`接入,选择对应进程即可监控。支持多Java进程管理,为后续深入使用奠定基础。(239字)
|
设计模式 Java Apache
Springboot项目优化日志logback-spring.xml详解
Commons Logging和Slf4j是日志门面(门面模式是软件工程中常用的一种软件设计模式,也被称为正面模式、外观模式。它为子系统中的一组接口提供一个统一的高层接 口,使 得子系统更容易使用)。log4j和Logback则是具体的日志实现方案。可以简单的理解为接口与接口的实现,调用这只需要关注接口而无需关注具体的实现,做到解耦
2875 0
Springboot项目优化日志logback-spring.xml详解
|
2月前
|
Java 数据库连接 调度
xxljob
本文深入分析XXL-JOB执行源码,涵盖架构设计与核心模块实现。包含带中文注释的源码包及流程图,详解国际化初始化、任务触发线程池(快慢池机制)、注册中心心跳检测、失败重试告警、任务结果丢失处理、日志清理及时间轮调度等核心逻辑,助你全面掌握其原理。
|
2月前
|
存储 算法 BI
XXLJob
本文介绍XXL-JOB本地运行全流程:下载源码后,导入数据库并启动服务端,配置数据源,访问管理后台;客户端启动后自动注册执行器,通过控制台配置调度任务与路由策略,支持多种执行模式如轮询、随机、分片广播等,并可实时查看执行日志,完成任务测试与调试。
|
2月前
|
前端开发 NoSQL Java
jeecgboot 单体版本
JeecgBoot单体版简介:基于Spring Boot 2.7 + Vue3 + TypeScript + Vite5,集成MybatisPlus、Shiro、Redis、Nacos等技术,支持代码生成、权限管理与微服务架构。前端使用Ant-Design-Vue,提供在线表单开发与低代码能力,快速构建企业级应用,适用于农商行笔试题等场景开发。(239字)
|
2月前
|
Java Nacos 数据安全/隐私保护
ruoyi 微服务版本
若依(RuoYi-Cloud)是基于Spring Boot、Spring Cloud与Alibaba的分布式微服务权限管理系统,支持Vue3前端。含网关、认证、系统、监控等模块,集成Nacos、Sentinel,提供代码生成、定时任务等功能,适用于快速构建企业级云架构应用。
|
2月前
|
SpringCloudAlibaba Java Nacos
SpringCloud概述
Spring Cloud应微服务需求而生,提供一站式解决方案,具备约定优于配置、组件丰富、云原生适配等特点。通过版本命名规范避免子项目冲突,结合Alibaba生态形成更完善的微服务技术栈,成为主流选择。
|
2月前
|
Java 大数据
ArrayList扩容机制
本文详解ArrayList扩容机制:首次添加元素时默认扩容至10,之后每次扩容为原容量的1.5倍。通过add、ensureCapacityInternal及grow方法分析扩容流程,并结合代码解析容量变化与性能优化原理,帮助理解动态数组底层实现。