优先用普通for循环(索引遍历),因ArrayList的get(i)为O(1),JVM对其有循环展开、范围检查消除等优化,实测比增强for快10%–20%,且避免迭代器对象分配和自动装箱开销。

遍历 ArrayList 大量数据时,性能关键在于避免重复计算、减少对象创建、利用 JVM 优化特性,并选择最匹配场景的遍历方式。ArrayList 是基于数组实现的,支持随机访问,所以 for 循环(基于索引)通常比 foreach 或 Iterator 更快,尤其在数据量大(如百万级)且仅需读取时。
优先用普通 for 循环(索引遍历)
因为 ArrayList 的 get(i) 是 O(1) 时间复杂度,且现代 JVM 对这种模式做了大量优化(如循环展开、范围检查消除),实测比增强 for 快 10%–20%(尤其在 HotSpot Server 模式下)。
- 写法简洁:直接用
list.get(i),不触发迭代器对象分配 - 避免自动装箱开销:遍历
ArrayList<integer></integer>时,for (int i = 0; i 不会额外创建 Integer 实例 - 注意:把
list.size()提前缓存,避免每次循环都调用(虽然 JIT 可能优化,但显式缓存更稳妥)
需要条件过滤或中途退出时,用增强 for(for-each)更安全清晰
语法简洁、不易出错,JVM 同样会将其编译为基于索引的字节码(对 ArrayList),性能差距极小;且避免手写索引越界风险。
- 适合:查找首个匹配项、统计满足条件的数量、简单处理逻辑
- 不适合:边遍历边 remove(会抛 ConcurrentModificationException),此时应改用迭代器的
remove() - 示例:
for (String s : list) { if (s.startsWith("A")) return s; }
并发或需安全移除时,用 Iterator 显式控制
这是唯一支持遍历中安全删除元素的方式(调用 iterator.remove()),底层复用数组移动逻辑,比反复调用 list.remove(obj) 高效得多。
立即学习“Java免费学习笔记(深入)”;
- 不要用 for-each + list.remove() —— 会抛异常且效率低
- 批量删除建议先收集待删索引,再倒序删除,或用
removeIf()(Java 8+,内部优化为单次数组复制) - 多线程场景下,ArrayList 本身不安全,应换用
CopyOnWriteArrayList(读多写少)或加锁,而非依赖遍历方式
超大数据量(千万级+)且只读,考虑流式分块或并行处理
单线程遍历已接近内存带宽瓶颈,可借助 parallelStream() 利用多核,但要注意:
- 并行流有启动开销,数据量小于约 10 万时通常比串行慢
- 确保操作无状态、无副作用(如不修改共享变量)
- 若需顺序结果(如生成新列表),用
stream().collect()而非parallelStream().forEach()(后者不保证顺序)


















