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. 大数据量场景一定要指定初始容量,优化性能。

相关推荐
侠客行031710 小时前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪10 小时前
深入浅出LangChain4J
java·langchain·llm
子兮曰10 小时前
OpenClaw入门:从零开始搭建你的私有化AI助手
前端·架构·github
吴仰晖10 小时前
使用github copliot chat的源码学习之Chromium Compositor
前端
1024小神10 小时前
github发布pages的几种状态记录
前端
老毛肚11 小时前
MyBatis体系结构与工作原理 上篇
java·mybatis
风流倜傥唐伯虎12 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
不像程序员的程序媛12 小时前
Nginx日志切分
服务器·前端·nginx
Yvonne爱编码12 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚12 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言