ArrayList扩容机制

简介: 本文深入分析了ArrayList的add及扩容机制。添加首个元素时触发ensureCapacityInternal,初始容量为10;当元素数超过当前容量时,调用grow方法将容量扩充至原1.5倍,通过位运算提升性能,并结合minCapacity与MAX_ARRAY_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);

}

我们来仔细分析一下
1当我们要add进第一个元素到ArrayList时,elementData.length为0(因为还是一个空的list,里面还没有数据,所以没有进行扩容,默认扩容10),因为执行了ensureCapacityInternal()方法,所以minCapacity此时为10。此时,minCapacity - elemetData.length > 0(minCapacity=10,elemetData.length=0)成立,所以会进入==grow(minCapacity)==方法。
2当add第2个元素时,minCapacity为2,此时elementData.length(容量)在添加第一个元素后扩容成10了。此时,minCapacity - elementData.length > 0不成立,所以不会进入(执行)==grow(minCapacity)==方法。
3添加第3、4…到第10个元素时,依然不会执行==grow()==方法,数组容量都为10。知道添加第11个元素,minCapacity(为11)比elementData.length(为10)要大。进行grow方法进行扩容
4grow方法

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() 方法是针对泛型集合说的,如果想看这个泛型有多少元素,就调用此方法类查看!


相关文章
|
5月前
|
安全 Java 应用服务中间件
|
缓存 数据处理 Android开发
Android经典实战之Kotlin常用的 Flow 操作符
本文介绍 Kotlin 中 `Flow` 的多种实用操作符,包括转换、过滤、聚合等,通过简洁易懂的例子展示了每个操作符的功能,如 `map`、`filter` 和 `fold` 等,帮助开发者更好地理解和运用 `Flow` 来处理异步数据流。
683 4
java常见的集合类有哪些
Map接口和Collection接口是所有集合框架的父接口: 1. Collection接口的子接口包括:Set接口和List接口 2. Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及 Properties等 3. Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等 4. List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等
|
存储 算法 Java
面试必备!一文搞懂HashMap如何优雅处理哈希冲突
大家好,我是小米,一个积极的程序员。今天聊聊Java面试中的常见问题——“HashMap是怎么解决哈希冲突的?”。通过一个小故事,我们了解到HashMap使用链地址法(JDK 1.8前)和红黑树(JDK 1.8后)来处理哈希冲突。链地址法用链表存储冲突的元素,而红黑树在链表长度超过8时启用,提升查找效率。希望这个讲解能帮助你更好地理解HashMap的工作原理。欢迎留言讨论,关注我的公众号“软件求生”,获取更多技术干货!
613 3
|
存储 缓存 Java
大厂面试高频:Volatile 的实现原理 ( 图文详解 )
本文详解Volatile的实现原理(大厂面试高频,建议收藏),涵盖Java内存模型、可见性和有序性,以及Volatile的工作机制和源码案例。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:Volatile 的实现原理 ( 图文详解 )
|
存储 缓存 JavaScript
深入理解JavaScript中的核心内容
本文全面介绍了JavaScript的基础与进阶知识。首先,概述了JavaScript作为一门脚本语言的基本概念,包括ECMAScript、DOM及BOM的作用与重要性。接着,深入探讨了JavaScript的执行流程,从编译到执行阶段,并重点讲解了JIT编译技术如何提升执行效率。随后,介绍了进阶知识点,如闭包的强大功能及其潜在的内存问题,`this`关键字的不同行为,以及事件循环机制如何管理同步与异步代码。通过本文的学习,读者不仅能掌握JavaScript的核心概念,还能深入了解其实现细节与最佳实践,为高效开发打下坚实基础。
214 1
深入理解JavaScript中的核心内容
|
存储 Android开发
android Jetpack—ViewModel使用方法和详细原理解析
android Jetpack—ViewModel使用方法和详细原理解析
1437 0
android Jetpack—ViewModel使用方法和详细原理解析
|
设计模式 Java API
实战分析Java的异步编程,并通过CompletableFuture进行高效调优
【6月更文挑战第7天】实战分析Java的异步编程,并通过CompletableFuture进行高效调优
459 2
|
弹性计算 Linux 云计算
云服务器 ECS产品使用问题之幻兽帕鲁服务器角色存档丢失,该怎么办
云服务器ECS(Elastic Compute Service)是各大云服务商阿里云提供的一种基础云计算服务,它允许用户租用云端计算资源来部署和运行各种应用程序。以下是一个关于如何使用ECS产品的综合指南。
|
存储 运维 监控

热门文章

最新文章