侧边栏壁纸
博主头像
MD_Tech_博客

行动起来,活在当下

  • 累计撰写 8 篇文章
  • 累计创建 8 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

ArrayList扩容机制

Siuux_7
2025-03-07 / 0 评论 / 0 点赞 / 6 阅读 / 0 字

ArrayList

ArrayList底层维护了一个 Object[] elementData数组以及n int size属性,elementData储存了元素对象,size属性为elementData数组的长度以及下次存储元素的索引位置。所以ArrayList本质上是一个动态数组,需要动态扩容机制才能满足不断添加元素的需求。

ArrayList的扩容机制:

  • 当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍
  • 如果直接使用指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容为elementData为1.5倍(多数情况下)

ArrayList的无参构造函数

ArrayList无参构造器.png
无参构造其实是为 elementData赋值了一个默认的空数组,DEFAULTCAPACITY_EMPTY_ELEMENTDATA,所以当使用无参构造器初始化时,他的初始容量为0.

ArrayList的有参构造函数

ArrayList有参构造器.png
分析源码可知,最终会指定elementData的长度为形参长度(输入值合法)

ArrayList的扩容机制

ArrayList扩容机制.png
使用无参构造器初始化ArrayList时,第一次执行add()方法时,最终会进入到grow()方法来判断是否进行扩容,oldCapacity为0,elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA,所以最后会执行 return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)],最后返回一个长度为10的数组。

当第十一次执行add()方法,执行到 s==element.length,判断出需要扩容,最终会落入到以下代码。

if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {  
    int newCapacity = ArraysSupport.newLength(oldCapacity,  
            minCapacity - oldCapacity, /* minimum growth */  
            oldCapacity >> 1           /* preferred growth */);  
    return elementData = Arrays.copyOf(elementData, newCapacity);  
}
  1. >>2 相当于/2
  2. ArraysSupport.newLength()方法用计算新数组的长度确保扩容时既能满足所需的最小容量 (minCapacity),又不会超出最大允许的数组大小 (MAX_ARRAY_SIZE,即 Integer.MAX_VALUE - 8)。
    规则:newLength = oldLength + Math.max(minGrowth, prefGrowth)

所以新数组的大小最终为15,原数组大小*1.5 倍。

分析源码可知,只有当原数组的长度为1、2或者3时,新数组的长度才会是原数组的长度+1

0

评论区