ArrayList扩容机制
从源码分析
ArrayList是List接口的实现类,它是支持根据需要而动态增长的数组。java中标准数组是定长的,在数组被创建之后,它们不能被加长或缩短。这就意味着在创建数组时需要知道数组的所需长度,但有时我们需要动态程序中获取数组长度。ArrayList就是为此而生的。
因此,了解它的扩容机制对使用它尤为重要。
- ArrayList扩容发生在调用add()方法的时候,下面是add()方法的源码:
- 存放元素的数组:elementData
| public boolean add(E e) { |
| |
| ensureCapacityInternal(size + 1); |
| elementData[size++] = e; |
| return true; |
| } |
- 根据意思可以看出ensureCapacityInternal()是用来扩容的,形参为最小扩容量,进入此方法后:
| private void ensureCapacityInternal(int minCapacity) { |
| ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); |
| } |
| private static int calculateCapacity(Object[] elementData, int minCapacity) { |
| |
| if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { |
| return Math.max(DEFAULT_CAPACITY, minCapacity); |
| } |
| return minCapacity; |
| } |
- ensureExplicitCapacity方法可以判断是否需要扩容:
| private void ensureExplicitCapacity(int minCapacity) { |
| modCount++; |
| |
| if (minCapacity - elementData.length > 0) |
| |
| grow(minCapacity); |
| } |
- 接下来重点来了,ArrayList扩容的关键方法grow():
| private void grow(int minCapacity) { |
| |
| int oldCapacity = elementData.length; |
| |
| int newCapacity = oldCapacity + (oldCapacity >> 1); |
| |
| |
| if (newCapacity - minCapacity < 0) |
| newCapacity = minCapacity; |
| |
| if (newCapacity - MAX_ARRAY_SIZE > 0) |
| newCapacity = hugeCapacity(minCapacity); |
| |
| |
| elementData = Arrays.copyOf(elementData, newCapacity); |
| } |
- 从方法中我们可以清晰的看出其实ArrayList扩容的本质就是计算出新的扩容数组的size后实例化,并将原有数组内容复制到新数组中去。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析