ArrayList底层实现原理

简介: ArrayList底层实现原理

上次咱们讲了常用的几个Map的原理,接下来咱们接着探讨下Map的兄弟,几个常用List的底层实现原理,首先要说的肯定是ArrayList吧,这用的多吧,来来来,上干货。


首先明确一点,Arraylist是基于动态数组实现的,就如同他名字一样,Array=数组,那动态数据是什么意思呢?我们都知道,数组一旦确定了大小是不可变的,动态数据说的通俗点就是可以变化长度的普通数组(其实底层实现还是数组,只不过用了复制转移等方法来实现数组长度变化),咱们接着看看Arraylist的底层数组到底是怎么操作的吧。


首先我们先看看Arraylist是怎么新加元素的吧add("111"),其实就是给数组里增加了一个元素,很简单如图:

插入元素呢add(2, "000"),我们基于数组实现的所以Arraylist是可以支持在指定下标插入元素的,整个过程是这样子的,比如我们要在数组下标2的位置插入一个000,他会首先把当前数组下标2位置以及之后的元素都往后面复制一遍(System.arraycopy方法),然后再把数组下标2的位置填上要插入的元素,底层的样子应该是这个样子的:

接着再来看看删除元素的时候是怎么操作的remove("333"),同样的道理在删除元素的下标位置之后的元素全部前移复制System.arraycopy方法最后一个元素会null,gc会把的null元素回收掉。

扩容呢,Arraylist如果初始不设置数组大小,默认的是10,当我们新增的数据超过10的时候就需要扩容,默认的扩容是1.5倍的扩容。细心的小伙伴又发现了,如果我本次存的数据是20大小怎么办,1.5倍=15不够了,是的没错,这里其实是个三目运算法,如果20大于15就取20作为这次扩容后的数组的大小,如果本次需要的小于15就取15作为本次扩容后的数组的大小,扩容完怎么办,要把原来数组里面的10个元素复制过来到新数组,就完了如图。

有人就问了,不能无限制的扩容吧,最大是多少,贴一段源码看看,第20行,当想扩容的大小.>最大数组长度,会调用一个hugeCapacity方法,用最小需要容量和最大数组长度比较,如果最小需要容量>最大数组长度则用Integer.MAX_VALUE作为数组长度,否则取最大数组长度作为新数组长度,有点绕,大家可以根据源码一起理解下。

Arraylist底层因为是数组,可以通过下标快速的访问查询等,但是,是不是发现问题了,每次插入元素,删除元素,或者扩容的时候,都要复制一波元素,是不是明白为啥说,删除,特殊点插入的效率就低,比较适合顺序添加、随机访问的场景这句话了。


再稍微扩展一点,有一个底层实现和Arraylist及其相似的Vector,只不过Arraylist是线程不安全的(可以把你的list变成List<String> synchronizedList = Collections.synchronizedList(list);来实现线程安全),方法都不是同步的,Vector线程安全的,主要的不同点就是这,还有个不同点是扩容不一样,一个是默认1.5倍,Vector是两倍。其他和LinkList的比较在下一篇文章里介绍。


最后,大家想获取更多知识的,可以继续关注公众号,不定时推送。分享了这么牛逼的知识,还不请小编喝个水吗,哈哈哈,欢迎土豪直接赏赞,谢谢,您的支持就是小编最大的动力。

相关文章
|
SQL 索引
19. 一个SQL语句执行很慢, 如何分析
该内容介绍了如何分析执行慢的SQL语句。首先启用慢查询日志或使用命令获取慢查询的SQL。然后利用`EXPLAIN`命令分析,关注其中的`select_type`, `type`, 和 `extra`字段。`select_type`涉及子查询和联合查询的类型,`type`表示查询优化器使用的访问类型,性能从上到下递减,`extra`字段提供额外信息,如是否使用索引等。
297 0
|
前端开发 API 数据库
鸿蒙开发:异步并发操作
在结合async/await进行使用的时候,有一点需要注意,await关键字必须结合async,这两个是搭配使用的,缺一不可,同步风格在使用的时候,如何获取到错误呢,毕竟没有catch方法,其实,我们可以自己创建try/catch来捕获异常。
424 3
鸿蒙开发:异步并发操作
|
12月前
|
机器学习/深度学习 人工智能 算法
2025年,程序员的黄金时代才刚开始-千万不要错误的以为程序员很多哟-卓伊凡软件行业洞察 前言
2025年,程序员的黄金时代才刚开始-千万不要错误的以为程序员很多哟-卓伊凡软件行业洞察 前言
1241 1
2025年,程序员的黄金时代才刚开始-千万不要错误的以为程序员很多哟-卓伊凡软件行业洞察 前言
|
NoSQL 物联网 atlas
浅析通过MongoDB一起解锁工业4.0转型的无限潜力!
MongoDB在智能制造中发挥关键作用,通过其开发者数据平台提升工业4.0的潜能,实现生产效率的提高和成本降低。借助MongoDB Atlas,企业能实时洞察、增强整体设备效率,构建现代物联网应用。MongoDB助力企业数字化转型,通过西门子数字化工厂、RideKleen、Longbow Advantage和博世数字等案例展示了其在提高生产灵活性、保障高可用性、加速创新和实现无缝数据同步方面的优势。MongoDB使制造企业能够应对数据挑战,优化运营,提升客户体验。
|
SQL 人工智能 自然语言处理
【AI 技术分享】大模型与数据检索的探索实践
本文基于2024年9月27日与阿里云合办的线下沙龙分享整理而成,探讨如何通过大语言模型(LLM)让数据访问更简单。随着企业数据量增长,传统数据访问方式已难以满足需求。LLM结合自然语言检索,使非技术用户能直接用自然语言与数据交互,降低数据访问门槛。文章介绍了NL2SQL技术,通过LLM理解自然语言问题并生成SQL查询,实现高效数据获取。同时,探讨了AskTable架构及其在实际应用中的挑战与解决方案。
1360 5
【AI 技术分享】大模型与数据检索的探索实践
|
开发框架 Java 关系型数据库
Java哪个框架适合开发API接口?
在快速发展的软件开发领域,API接口连接了不同的系统和服务。Java作为成熟的编程语言,其生态系统中出现了许多API开发框架。Magic-API因其独特优势和强大功能,成为Java开发者优选的API开发框架。本文将从核心优势、实际应用价值及未来展望等方面,深入探讨Magic-API为何值得选择。
589 2
|
存储 Ubuntu 应用服务中间件
如何在 Ubuntu 上安装和使用 Nginx?
ginx(发音为“engine-x”)是一种流行的 Web 服务器软件,以其高性能和可靠性而闻名。它是许多流行网站使用的开源软件,包括 Netflix、GitHub 和 WordPress。Nginx 可以用作 Web 服务器、负载均衡器、反向代理和 HTTP 缓存等。
1796 0
|
并行计算 编译器 C#
"CMake高手进阶秘籍:解锁高级技巧,实践最佳策略,让你的项目构建如丝般顺滑,效率飙升!"
【8月更文挑战第11天】CMake是现代软件开发的关键构建系统,其跨平台与灵活配置特性简化了复杂项目的构建流程。本文探讨CMake的高级技巧与最佳实践,包括升级至最新版本以利用新功能;采用面向目标的编程方法,增强项目清晰度与可维护性;运用CMake预设统一多平台构建配置;掌握调试技巧快速定位问题;集成代码检查与格式化工具保障代码质量;以及启用并行构建提升构建效率。通过这些策略,开发者能够更高效地管理大型项目。
445 3
|
存储 Java
Java中的ArrayList的设计思想与底层原理剖析
Java中的ArrayList的设计思想与底层原理剖析
347 1

热门文章

最新文章