ArrayList 的扩容机制解析

简介: ArrayList扩容机制解析:添加元素时先检查容量,不足则触发扩容。默认初始容量为10,每次扩容1.5倍,通过数组拷贝实现,耗时O(n)。频繁扩容影响性能,建议预估容量并初始化指定大小,提升效率。


ArrayList 是 Java 中最常用的动态数组实现,其核心优势在于自动扩容——无需预先指定容量,即可按需增长。但这一“便利”背后,有一套严谨的扩容逻辑。


一、添加元素时触发扩容检查

当我们调用 add(E e) 方法时,ArrayList 并不会直接将元素放入数组,而是先检查容量是否足够

public boolean add(E e) {
    ensureCapacityInternal(size + 1); // 检查并确保容量
    elementData[size++] = e;          // 赋值
    return true;
}

关键在 ensureCapacityInternal 方法。


二、扩容的核心逻辑

  1. 默认初始容量
    若使用无参构造(new ArrayList<>()),底层 elementData 初始为一个空数组。首次添加元素时,会初始化为容量 10
  2. 扩容规则size + 1 > 当前容量 时,触发扩容:
int newCapacity = oldCapacity + (oldCapacity >> 1); // 扩容 1.5 倍
  • 例如:当前容量 10 → 扩容后为 15;
  • 若仍不够(如一次性添加大量元素),则直接扩容到所需最小容量。
  1. 数组拷贝
    扩容通过 Arrays.copyOf(elementData, newCapacity) 实现,创建新数组并将旧数据复制过去。这是一个 O(n) 操作,代价较高。

三、性能启示

  • 频繁扩容影响性能:每次扩容都涉及内存分配与数据拷贝;
  • 建议预估容量:若已知元素数量,使用 new ArrayList<>(initialCapacity) 初始化,避免多次扩容;
  • Guava 推荐Lists.newArrayListWithCapacity(100) 可读性更佳。

四、示例对比

// 不推荐:多次扩容
List<String> list1 = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
    list1.add("item" + i);
}
// 推荐:一次到位
List<String> list2 = new ArrayList<>(1000);
for (int i = 0; i < 1000; i++) {
    list2.add("item" + i);
}

后者避免了约 10 次扩容(10 → 15 → 22 → 33 → ... → 1000),显著提升效率。


总结

ArrayList 的扩容机制以 1.5 倍增长平衡空间与时间开销,但在性能敏感场景下,主动指定初始容量是最佳实践。理解其底层原理,有助于写出更高效、更稳定的代码。


相关文章
|
监控 算法
探秘Guava的RateLimiter:单机流量控制的黄金法宝
探秘Guava的RateLimiter:单机流量控制的黄金法宝
789 0
|
6月前
|
存储 安全 Java
Java HashMap 全面解析:原理、用法与实战要点
本文深入解析Java中HashMap的底层原理与使用实践,涵盖其“数组+链表+红黑树”的结构演变、哈希计算、扩容机制及线程安全问题,详解常用方法、性能优化与最佳实践,助力开发者高效掌握这一核心数据结构。
1649 11
|
3月前
|
人工智能 文字识别 开发者
阿里云Token是什么?7000万免费额度能做什么?看完省下一大笔
阿里云新用户可领7000万免费Token:https://t.aliyun.com/U/fPVHqY 大模型Token是AI处理文本的基本单位(1个≈0.75个汉字),输入输出均计费。百炼平台百余款千问模型,每款各赠100万Token,有效期90天。相当于可写2.3万篇文章、4.7万次对话或处理933份百页文档,价值数百元。立即开通即享!
2386 12
|
12月前
|
JSON 缓存 API
身份证二要素核验接口调用指南 —— Python 示例
本文介绍如何在 Python 中快速实现身份证二要素核验功能,适用于用户注册、金融风控等场景。通过阿里云市场提供的接口,可校验「姓名 + 身份证号」的一致性,并获取性别、生日、籍贯等信息。示例代码展示了从环境变量读取 APP_CODE、发送 GET 请求到解析 JSON 响应的完整流程。关键字段包括 code(1-一致,2-不一致,3-无记录)、msg 和 data。常见问题如 403 错误需检查 AppCode,超时则优化网络或设置重试机制。集成后可根据业务需求添加缓存、限流等功能提升性能。
1018 4
|
9月前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
2921 0
|
设计模式 缓存 安全
Java设计模式的单例模式应用场景
Java设计模式的单例模式应用场景
432 4
|
存储 算法 安全
HashMap的实现原理,看这篇就够了
关注【mikechen的互联网架构】,10年+BAT架构经验分享。深入解析HashMap,涵盖数据结构、核心成员、哈希函数、冲突处理及性能优化等9大要点。欢迎交流探讨。
HashMap的实现原理,看这篇就够了
|
存储 安全 Java
ConcurrentHashMap是如何保证线程安全的?
ConcurrentHashMap相当于是HashMap的多线程版本,它的功能本质上和HashMap没什么区别。因为HashMap在并发操作的时候会出现各种问题,比如死循环问题、数据覆盖等问题。而这些问题,只要使用ConcurrentHashMap就可以完美地解决。那问题来到了,ConcurrentHashMap它是如何保证线程安全的呢?
452 0
|
安全 网络协议 Linux
yum出现Loaded plugins: fastestmirror, security Loading mirror speeds from cached hostfile解决方法
yum出现Loaded plugins: fastestmirror, security Loading mirror speeds from cached hostfile解决方法
3877 3
|
存储 Java
HashMap的扩容机制是怎样的
在Java中,HashMap 是一个基于哈希表的键值对集合,它以其高效的存取性能而广泛使用。HashMap 的扩容机制是其性能优化的关键部分,本文将详细介绍这一机制的工作原理和过程。

热门文章

最新文章