首页 游戏 软件 资讯 排行榜 专题
首页
编程语言
如何在 Java 中使用 ArrayList.ensureCapacity() 减少由于频繁增删导致的数组重分配

如何在 Java 中使用 ArrayList.ensureCapacity() 减少由于频繁增删导致的数组重分配

热心网友
42
转载
2026-05-01

如何在 Ja va 中使用 ArrayList.ensureCapacity() 减少由于频繁增删导致的数组重分配

如何在 Ja va 中使用 ArrayList.ensureCapacity() 减少由于频繁增删导致的数组重分配

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

ensureCapacity() 真的能减少重分配吗?

答案是肯定的,但这里有个关键前提:它只对“新增”操作有效,而且必须在执行大量 add() 之前就调用。至于 remove() 操作,这个方法完全帮不上忙,它也不会主动回收已经分配出去的空间。道理很简单,ArrayList 内部的数组扩容,只在 add() 发现容量不够时才会触发。而 ensureCapacity() 的作用,就是提前把底层的 elementData 数组扩大到指定尺寸,从而避免后续多次的 resize 操作——要知道,每次 resize 都意味着分配新数组和拷贝全部元素,这可是 O(n) 级别的开销。

这里有个常见的误解:有人以为调用一次 ensureCapacity(100),之后即使删除了90个元素,内存也会自动缩回来。其实不然。ArrayList 的设计决定了它从不自动缩小底层数组,想释放冗余内存,得靠另一个方法 trimToSize()。而且,这也不属于“减少重分配”的范畴,而是纯粹的内存回收行为。

什么时候调用 ensureCapacity() 才真正省开销?

最典型的场景,就是那种“可预估最终规模的批量构建”。比如,从数据库里查询出5000条记录逐条添加,或者解析一个已知长度的JSON数组。在这种情况下,于循环开始前调用 ensureCapacity(),就能完美避免多次扩容。想想看,默认初始容量只有10,按1.5倍的策略扩容,要装下5000个元素,中间至少得经历大约12次数组拷贝,这个开销可不小。

  • ✅ 推荐场景:已知最终的元素数量(比如在 list.size() == expectedSize 成立之前),并且主要操作是 add()
  • ❌ 无效场景:一边添加一边删除、或者进行随机位置的插入(add(int index, E) 虽然可能引发数组元素移动,但不会触发扩容逻辑)。
  • ⚠️ 特别注意ensureCapacity() 的参数是“最小需要容量”,而非“精确容量”。传入100,只保证数组长度不小于100;如果当前容量已经大于等于100,那这个方法就什么都不做。

和构造函数 initialCapacity 比,有啥区别?

从本质上讲,两者目的相同,都是设置初始数组大小。区别在于时机:new ArrayList(100) 在对象实例化时就分配好了数组;而 ensureCapacity(100) 则是对已经存在的实例进行“事后补救”。两者的实际性能差异微乎其微,但使用时机不同,能让代码语义更清晰:

  • 如果在构造时就已经清楚知道数据规模,直接用 new ArrayList(initialCapacity)
  • 如果实例已经存在,稍后才确定要装入大量数据,那就用 ensureCapacity()
  • 需要明确的是,无论哪种方式,都只影响底层数组的物理容量,而不改变 size() 返回的逻辑元素个数。调用之后,size() 依然是0。

来看一个具体例子:

ArrayList list = new ArrayList<>();
list.ensureCapacity(5000); // 底层数组现在至少长 5000
for (int i = 0; i < 5000; i++) {
    list.add("item" + i); // 全程无 resize
}

容易被忽略的坑:ensureCapacity() 不解决并发和结构性修改问题

即使你精准地调用了 ensureCapacity(),下面这些情况依然可能引发意外的性能开销甚至异常:

  • 多线程同时 add():即使容量充足,非线程安全的 ArrayList 也可能因竞争导致重复扩容。
  • 使用迭代器或条件删除:通过 list.iterator().remove()removeIf() 删除大量元素后,底层数组容量不变,但后续的 add() 仍会基于当前的 size() 判断扩容,可能造成严重的空间浪费。
  • 清空后复用:调用 clear() 后继续添加,虽然底层数组没变,但 size 已归零。如果之后只加几十个元素,那么之前预分配的5000容量就成了闲置内存。

所以说,预分配容量只是一种优化手段,不能替代对实际使用模式的判断。在真正高频增删的场景下,或许该考虑换成 LinkedList(插入删除快)、或者使用 ArrayDeque(作为栈或队列更高效),甚至评估对象池方案——而不是仅仅盯着 ensureCapacity() 这一个方法。

来源:https://www.php.cn/faq/2399804.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

使用位运算优化多条件状态报告的Java实现方法
编程语言
使用位运算优化多条件状态报告的Java实现方法

基于位运算的容差检测报告优化方案 在工业级数据校验场景中,比如木材尺寸的容差检测,我们常常需要根据多个布尔状态(如厚度、宽度、长度是否合格)来组合生成差异化的提示信息。传统的实现方式,往往是写下一长串的 if-else 分支,来覆盖所有可能的逻辑组合。功能虽然能实现,但问题也很明显:代码重复度高,扩

热心网友
05.01
如何在 Java 中使用 ArrayList.ensureCapacity() 减少由于频繁增删导致的数组重分配
编程语言
如何在 Java 中使用 ArrayList.ensureCapacity() 减少由于频繁增删导致的数组重分配

如何在 Ja va 中使用 ArrayList ensureCapacity() 减少由于频繁增删导致的数组重分配 ensureCapacity() 真的能减少重分配吗? 答案是肯定的,但这里有个关键前提:它只对“新增”操作有效,而且必须在执行大量 add() 之前就调用。至于 remove() 操

热心网友
05.01
如何在 Java 中利用 while 循环实现一个简单的基于时间轮算法的定时任务调度流程
编程语言
如何在 Java 中利用 while 循环实现一个简单的基于时间轮算法的定时任务调度流程

如何在 Ja va 中利用 while 循环实现一个简单的基于时间轮算法的定时任务调度流程 可行但仅适用于学习、嵌入式或教学场景;生产环境应优先选用 HashedWheelTimer、ScheduledThreadPoolExecutor 或 Quartz。 在 Ja va 中,用 while

热心网友
05.01
如何在 Java 中使用 String.matches() 编写带有“零宽断言”的高级正则校验表达式
编程语言
如何在 Java 中使用 String.matches() 编写带有“零宽断言”的高级正则校验表达式

如何在 Ja va 中使用 String matches() 编写带有“零宽断言”的高级正则校验表达式 说起 Ja va 里的 String matches() 方法,很多开发者都踩过同一个坑:它要求正则表达式必须从头到尾、完完整整地匹配整个字符串。这相当于在模式前后自动加上了 ^ 和 $。所以,当

热心网友
05.01
怎么在 Java 中使用 String.format() 实现类似 C 语言的格式化输出
编程语言
怎么在 Java 中使用 String.format() 实现类似 C 语言的格式化输出

怎么在 Ja va 中使用 String format() 实现类似 C 语言的格式化输出 String format() 的基本语法和占位符怎么写 很多从 C 语言转过来的开发者,会下意识地把 printf 那套写法直接搬到 Ja va 里。但这里有个关键区别:Ja va 的 String for

热心网友
05.01

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

《洛克王国:世界》隐藏极品精灵蛋获取攻略
游戏攻略
《洛克王国:世界》隐藏极品精灵蛋获取攻略

洛克王国世界隐藏极品精灵蛋获取方法全解析 各位《洛克王国:世界》的训练家们,你是否已经探索了地图上的每一个角落?游戏中其实散布着一些极易被忽略的隐藏宝藏——属性近乎完美的极品精灵蛋。它们潜藏在特定遗迹中,即便完成了主线剧情,许多玩家也可能与之失之交臂。本文将为你悉数揭秘这些稀有精灵蛋的精准位置与获取

热心网友
05.01
cr8.art : AI辅助艺术创作
AI
cr8.art : AI辅助艺术创作

需求人群 首先,艺术创作领域的工作者。无论是绘画、设计,还是数字媒体艺术家,一个能够持续激发灵感的工具总是备受青睐。 上图所示平台,正是为这一群体量身打造的解决方案。 产品特色 那么,它具体能带来哪些不一样的助力?我们不妨拆开来看。 首当其冲的,自然是利用AI技术生成创作灵感。创意枯竭的瓶颈期,谁没

热心网友
05.01
小K电商图-低成本打造优质电商图片
AI
小K电商图-低成本打造优质电商图片

「小K电商图」是什么 简单来说,这是一款商用级的电商AIGC图片工具。它的核心价值,就在于能用极低的成本,帮电商从业者产出高质量的营销图片。对于预算和效率都有要求的团队,这无疑是个值得关注的解决方案。 功能解析 功能设计直击行业痛点,每一项都很有针对性: 无需模特和摄影师:这是成本控制的关键。理论上

热心网友
05.01
《洛克王国:世界》炫彩翼王和龙息帕尔选择推荐
游戏攻略
《洛克王国:世界》炫彩翼王和龙息帕尔选择推荐

洛克王国世界炫彩翼王和龙息帕尔怎么选?平民玩家棱镜球使用指南 许多《洛克王国:世界》的玩家手中仅有一颗珍贵的棱镜球,面对炫彩翼王和炫彩龙息帕尔这两只人气宠物,常常陷入难以抉择的困境。毕竟,棱镜球作为一种稀有的养成资源,获取途径有限,一旦用错便会感到十分可惜。那么,这两只炫彩宠物究竟哪一只更值得你投入

热心网友
05.01
《明日方舟:终末地》洛茜抽取建议
游戏攻略
《明日方舟:终末地》洛茜抽取建议

明日方舟终末地洛茜值得抽吗 全面分析卡池价值与阵容搭配 《明日方舟:终末地》全新六星干员‌洛茜‌,将于‌3月29日12:00‌正式进驻下半段限定卡池【狼珀】特许寻访。这位备受期待的物理 火焰混伤干员,其抽取价值主要取决于玩家现有阵容的构建需求。本文将为你深入解析洛茜的强度定位与适用场景,助你做出最明

热心网友
05.01