ArrayList底层源码解析
Java源码系列:下方连接
http://t.csdn.cn/Nwzed
文章目录
- 前言
- 一、**ArrayList底层结构和源码分析**
- 无参构造调用创建ArrayList集合
- 无参构造总结:发文3个工作日后 up 会把总结放入前言部分,但也诚邀读者总结,可放入评论区
- 有参构造器调用创建ArrayList集合
前言
ArrayList集合总结:发文3个工作日后 up 会把总结放入前言部分,可谓“温故而知新”。
提示:以下是本篇文章正文内容,下面案例可供参考
一、ArrayList底层结构和源码分析
无参构造调用创建ArrayList集合
创建ArrayList时没有传参数调用的无参构造,无参构造把默认的常量 DEFAULTCAPACITY_EMPTY_ELEMENTDATA
赋值给了成员变量 elementData,所以elementData初始化的时候就是一个空数组。
从自动装箱出来,再次点进add方法会来到下面代码
进来 add 方法不是一上来就把 e 存入 elementData默认数组,而是先确保数组的容量够不够,因为默认的数组容量是空的没有指定数据的容量,而现在我们又在底层源码,没办法一上来就往一个空数组里面放数据,所有会先调用 ensureCapacityInternal(size + 1) 这时数组的size肯定是 0 , 0+1肯定大于1,拿到这个 1 后我们接着步入 ensureCapacityInternal方法。
步入到 ensureCapacityInternal 确保内部容量 方法就会把刚才的 1 传过来。接着调用 calculateCapacity计算容量 方法来确定数组的容量。
步入到 calculateCapacity 方法,先判断传入的 elementData和默认的DEFAULTCAPACITY_EMPTY_ELEMENTDATA空数组是否相等,相等会在这里拿到默认初始容量 DEFAULT_CAPACITY (10)和 add 方法传过来的 1 ,调用 Math.max()进行比较。
继续步入 Math.max()方法,里面第一个参数是 默认初始容量 DEFAULT_CAPACITY (10),第二个是 1,接下来进行判断 a>=b? 也就是 10>=1?,为true返回 a(DEFAULT_CAPACITY )。
得到结果 后一路返回到 ensureCapacityInternal 方法,因为上一次调用 ensureCapacityInternal 执行的是ensureExplicitCapacity里面的calculateCapacity计算容量方法进行容量的确定,一路返回过来就该执行ensureExplicitCapacity 确保显式容量方法了。
继续步入到确保显示容量,一进来就会让 modCount++ 这是为了确保多线程进来随意篡改集合内容做的计数器。
继续步入 grow 方法,这时才真正进行扩容,
将 minCapactiy的值赋值给newCapactiy后再进行判断是否大于最大值,其实这个判断不是给我们通过无参构造使用的,因为无参构造的初始容量就是10,不可能比最大的值大,到最后调用 Arrays.copyOf( )方法进行数组的拷贝,然后赋值给 elementData 覆盖一开始的空数组,这样就完成了ArrayList的初始化。
Arrays.copyOf( )方法在进行数组的拷贝时会保留原来数组的内容到新的数组。
第一次初始化扩容数组的长度是 10 ,之后的扩容就是 1.5 倍。
等copyOf执行完后会一路返回到刚开始调用到 add 的地方,把 e 的值赋值给 elementData[ size (0)]数组下标为 0 的地方,赋值之后再让 size++,以便下一个数据存入下标为 1 的位置。
由于我们最外层写的是一个for循环添加ArrayList数据,所以以上步骤会重复执行。但要注意的是,只有在存入数据时数组满了,才会去扩容。数组的扩容我们并不需要去担心,因为在调用 add 方法添加数据时,会先调用 ensureCapacityInternal(size + 1);
方法进行确保内部容量计算,如果当前数组的长度加1减去elementData.length 大于 0 就进行扩容。
if (minCapacity - elementData.length > 0) grow(minCapacity);
无参构造总结:发文3个工作日后 up 会把总结放入前言部分,但也诚邀读者总结,可放入评论区
有参构造器调用创建ArrayList集合
点进有参构造器,就会拿到传入的int数据去构建一个 new Object[ ] 的数组,赋值给 elementData,如果传过来的是一个0就和无参构造的一样,如果传入的是负数就抛异常。
除了初始化时不一样,其他地方都是差不多的,比如自动装箱,然后调用 add 方法,然后去调用ensureCapacityInternal方法
调用ensureCapacityInternal方法时,elementData数组的长度不再是 0 ,而是我们自定义的长度。
在往ArrayList添加数据时,如果没有超出自定义的数组边界是不会去调用 grow 方法进行数组扩容的。
然后一路返回到 add 方法进行元素的添加,直到添加元素时ensureCapacityInternal方法计算出 if(minCapacity - elementData.length > 0) grow(minCapacity);
时才会去做1.5倍扩容。
相关文章:

ArrayList底层源码解析
Java源码系列:下方连接 http://t.csdn.cn/Nwzed 文章目录前言一、**ArrayList底层结构和源码分析**无参构造调用创建ArrayList集合无参构造总结:发文3个工作日后 up 会把总结放入前言部分,但也诚邀读者总结,可放入评论区有参构造…...

python:DIY字符画的程序使用说明.doc
目录开发环境要求运行方法具体的操作步骤如下:代码示例源码及运行程序下载地址开发环境要求 本系统的软件开发及运行环境具体如下。 操作系统:Windows 7、Windows 10。 Python版本:Python 3.7.0。 开发工具:Python IDLE。 …...

【Python/Opencv】图像权重加法函数:cv2.addWeighted()详解
【Python/Opencv】图像权重加法函数:cv2.addWeighted()详解 文章目录【Python/Opencv】图像权重加法函数:cv2.addWeighted()详解1. 介绍2. API3. 代码示例与效果3.1 代码3.2 效果4. 参考1. 介绍 在OpenCV图像加法cv2.add函数详解详细介绍了图像的加法运…...
容器的老祖宗LXC和Docker的关系
一、什么是LXC? LXC(Linux Container的缩写)是一个基于Linux内核的容器虚拟化技术,它提供了一种轻量级、快速、简便的方式来创建和管理系统容器。与传统虚拟化技术不同,LXC并不会模拟硬件,而是利用Linux内…...
Webpack迁移Rspack速攻实战教程(前瞻版)
前言 rspack 即将开源,但社区中不乏有已经落地的 case ,比如 rspack-migration-showcase 、 modern.js 等。 基于此,本文将介绍如何迁移一个近似于 CRA( create-react-app ) 的项目到 rspack 。 在阅读本文前&#…...

一行代码“黑”掉任意网站
文章目录只需一行代码,轻轻一点就可以把任意网站变成暗黑模式。 首先我们先做一个实验,在任意网站中,打开浏览器开发者工具(F12),在 C1onsole 控制台输入如下代码并回车: document.documentElement.style.filterinve…...

51单片机入门 -驱动 8x8 LED 点阵屏
硬件型号、软件版本、以及烧录流程 操作系统:Windows 10 x84-64单片机:STC89C52RC编译器:SDCC烧录软件:stcgal 1.6开发板:普中51单片机开发板A2套件(2022) 在 VS Code 中新建项目到烧录的过程…...

Xinlinx zynq7045国产替代 FMQL45T900全国产化 ARM 核心板+扩展板
TES745D 是一款基于 FMQL45T900 的全国产化 ARM 核心板。该核心板将 FMQL45T900(与XC7Z045-2FFG900I 兼容)的最小系统集成在了一个 87*117mm 的核心板上,可以作为一个核心模块,进行功能性扩展,能够快速的搭建起一个信号…...

硬刚ChatGPT!文心一言能否为百度止颓?中国版ChatGPT“狂飙”的机会在哪儿?
文章目录目录产品背景发展历程科技简介主要功能合作伙伴结语文心一言 (英文名:ERNIE Bot) *是百度基于文心大模型技术推出的生成式对话产品,被外界誉为“中国版ChatGPT”,将于2023年3月份面向公众开放。 [40] 百度在人…...

Python 异步: 在非阻塞子进程中运行命令(19)
动动发财的小手,点个赞吧! 我们可以从 asyncio 执行命令。该命令将在我们可以使用非阻塞 I/O 写入和读取的子进程中运行。 1. 什么是 asyncio.subprocess.Process asyncio.subprocess.Process 类提供了由 asyncio 运行的子进程的表示。它在 asyncio 程序…...

蓝桥杯嵌入式第五课--输入捕获
前言输入捕获的考题十分明确,就是测量输入脉冲波形的占空比和频率,对我们的板子而言,就是检测板载的两个信号发生器产生的信号:具体来说就是使用PA15和PB4来做输入捕获。输入捕获原理简介输入捕获能够对输入信号的上升沿和下降沿进…...

Spring事务和事务传播机制
目录 Spring中事务的实现 1、通过代码的方式手动实现事务 2、通过注解的方式实现声明式事务 2.1、Transactional作用范围 2.2、Transactional参数说明 2.3、注意事项 2.4、Transactional工作原理 事务隔离级别 1、事务特性 2、Spring中设置事务隔离级别 2.1、MySQL事…...

基于OpenCV+CUDA实时视频抠绿、背景合成以及抠绿算法小结
一、关于抠绿 百度百科上描述抠绿“抠绿是指在摄影或摄像时,以绿色为背景进行拍摄,在后期制作时使用特技机的“色键”将绿色背景抠去,改换其他更理想的背景的技术。”绿幕的使用已经非常普遍,大到好莱坞大片,小到自媒体的节目,一些商业娱乐场景,几乎都用使用。但是很多非…...

MySQL 中的 UNION 语句
文章目录一、数据准备一、UNION 和 UNION ALL二、UNION 的执行顺序(UNION 和其他语句一同出现)三、MySQL 使用 UNION(ALL) ORDER 导致排序失效四、UNION 报错语法一、数据准备 -- 创建表 CREATE TABLE test_user (ID int(11) NO…...

高完整性系统工程(三): Logic Intro Formal Specification
目录 1. Propositions 命题 2.1 Propositional Connectives 命题连接词 2.2 Variables 变量 2.3 Sets 2.3.1 Set Operations 2.4 Predicates 2.5 Quantification 量化 2.6 Relations 2.6.1 What Is A Relation? 2.6.2 Relations as Sets 2.6.3 Binary Relations as…...

【linux】多线程概念详述
文章目录一、线程基本概念1.1 进程地址空间与页表1.2 页表结构1.3 线程的理解1.3.1 如何描述线程1.4 再谈进程1.5 代码理解1.5.1 原生库提供线程pthread_create1.6 资源共享问题1.7 资源私有问题二、总结2.1 什么是线程2.2 并行与并发2.3 线程的优点2.4 线程的缺点2.5 线程异常…...
【Java】P8 面向对象(3)方法 基本知识
面向对象 方法方法方法的声明权限修饰符返回值类型方法名形参列表方法体简单案例方法 方法 是对类或对象行为特征的抽象,用来完成某个功能的操作。方法的目的 是为了实现代码复用,减少冗余,简化代码;方法不能独立存在,…...
js中null和undefined的区别
js中null和undefined的区别?这也是一个常见的js面试题 相同点 1,都是基本类型。 2,做判断值都是false。 !!null false // true !!undefined false // true不同点 1,诞生时间null在前,undefined在后。因为js作者Brendan-Eic…...

【Linux】linux中的c++怎么调试?gdb的介绍和使用。
背景1.1.前提知识程序的发布方式有两种,debug模式和release模式Linux gcc/g出来的二进制程序,默认是release模式 要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项windows上的调试方法有区别吗?1.调试思路是一样的2…...

提升Python代码性能的六个技巧
文章目录前言为什么要写本文?1、代码性能检测1.1、使用 timeit 库1.2、使用 memory_profiler 库1.3、使用 line_profiler 库2、使用内置函数和库3、使用内插字符串 f-string4、使用列表推导式5、使用 lru_cache 装饰器缓存数据6、针对循环结构的优化7、选择合适算法…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

Android写一个捕获全局异常的工具类
项目开发和实际运行过程中难免会遇到异常发生,系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler,它是Thread的子类(就是package java.lang;里线程的Thread)。本文将利用它将设备信息、报错信息以及错误的发生时间都…...