Java集合“坑王”:ArrayList为啥越界还能浪?

提起ArrayList,新手总觉得它就是个"自动扩容的数组",随便add、get都不怕------直到遇到 IndexOutOfBoundsException ,才发现这货藏着不少小心机。今天咱扒一扒ArrayList的扩容黑科技,以及那些让你踩坑的细节!

一、先搞懂:ArrayList为啥能"自动变长"?

ArrayList底层是普通数组,默认初始容量是10。当添加元素导致数组满了,它会悄悄扩容:新容量=旧容量×1.5(源码里是 oldCapacity + (oldCapacity >> 1) ),然后把旧数组的数据复制到新数组。

看个简单例子,直观感受扩容:

java 复制代码
import java.util.ArrayList;

public class ArrayListDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>(); // 初始容量10
        
        // 加10个元素,刚好填满初始数组
        for (int i = 0; i < 10; i++) {
            list.add("元素" + i);
        }
        
        // 第11个元素:触发扩容!新容量变成15
        list.add("触发扩容的元素");
        
        System.out.println("当前元素数量:" + list.size()); // 输出11
        System.out.println("能存但未用的容量:" + (list.size() < 15 ? 15 - list.size() : "已再次扩容")); // 输出4
    }
}

二、踩坑重灾区:size和capacity别搞混!

很多人以为 list.size() 是数组容量,其实大错特错:

  • size() :实际存储的元素数量(你add了多少个)
  • capacity :底层数组的长度(ArrayList内部用 elementData 数组,容量不对外暴露)

这就是为啥 get(10) 会报错------哪怕数组容量是15,只要你只存了11个元素,索引10是有效的,但索引11就越界:

java 复制代码
public static void main(String[] args) {
    ArrayList<String> list = new ArrayList<>();
    for (int i = 0; i < 11; i++) {
        list.add("元素" + i);
    }
    
    System.out.println(list.get(10)); // 正常输出:元素10
    list.get(11); // 直接抛IndexOutOfBoundsException!
}

三、实用技巧:提前指定容量,避免频繁扩容

如果知道要存多少元素,初始化时直接指定容量,能减少数组复制的性能损耗:

java 复制代码
// 已知要存1000个元素,直接指定容量
ArrayList<String> list = new ArrayList<>(1000);
// 后续add1000个元素,一次扩容都不会触发

最后划重点

  1. ArrayList扩容是"偷偷摸摸"的,扩容后旧数组会被GC回收;

  2. 越界异常看的是 size() ,不是底层数组容量;

  3. 大数据量场景一定要指定初始容量,优化性能。

相关推荐
AAA简单玩转程序设计4 小时前
别再把Java枚举当“花瓶”!它能办大事
java·前端
Java天梯之路4 小时前
Spring Boot 启动流程源码解析:从 `main()` 到 Web 服务就绪
java·spring boot·面试
漂亮的小碎步丶4 小时前
【3】Spring事务管理
java·数据库·spring
knight_l4 小时前
【附源码,附两款可视化大屏】Three.js中的地图精确贴图与热力图实现解析
前端
华洛4 小时前
《回顾我的AI学习之路,上万字的AI学习思维导图分享》
前端·后端·产品经理
PBitW4 小时前
工作两年,从自己造轮子,变成使用开源项目!
前端·开源·若依·为什么使用开源项目·不自己造轮子
WZTTMoon4 小时前
Spring Boot Swagger3 使用指南
java·spring boot·后端·swagger3
cindershade4 小时前
Vue3 实时音频录制与转写 Composable 技术实现
前端
Java天梯之路4 小时前
Spring Boot 钩子全集实战(一):构造与配置阶段
java·spring boot·面试