arraylist用普通for循环最快,linkedlist用迭代器更优,遍历方式需匹配集合底层结构,盲目统一用iterator.hasnext()+next()未必高效。

Java 迭代器遍历本身不是性能瓶颈,真正影响效率的是集合类型、遍历方式与具体操作的匹配度。盲目套用 iterator.hasNext() + next() 并不总最快,关键在“选对方式、避开陷阱、按需定制”。
看集合类型选遍历方式
不同底层结构对迭代器的响应差异极大:
-
ArrayList:支持随机访问,普通 for 循环(
for (int i = 0; i )通常比迭代器快 10%–20%,因为免去 Iterator 对象创建和方法调用开销;增强 for 循环(底层仍是 Iterator)性能接近传统 for,但更简洁安全。 -
LinkedList:不支持高效随机访问,绝对避免
get(i)式遍历(时间复杂度 O(n²));必须用迭代器或增强 for,两者性能基本一致。 -
HashSet / LinkedHashSet:哈希表结构,迭代器遍历是唯一自然顺序方式;增强 for 和
iterator底层同源,性能无差别;若仅读取,三者(增强 for / iterator / forEach)实测差距<3%。 - TreeSet:红黑树有序,迭代器天然按排序顺序访问,无需额外排序成本。
避免遍历中高频副作用
看似无害的操作可能让迭代器变慢:
- 在
next()后反复调用list.get(i)或map.get(key)—— 尤其在 HashMap 中,重复哈希计算+寻址会显著拖慢;应直接使用当前元素(如遍历entrySet时用e.getKey()/e.getValue(),而非再map.get(e.getKey()))。 - 在循环体内创建对象(如 new StringBuilder())、装箱拆箱(遍历
List<integer></integer>却做int sum += element)会触发 GC 压力,建议提前声明复用变量或改用原始类型流(如list.stream().mapToInt(Integer::intValue).sum())。 - 不要在 foreach 或 iterator 循环里调用
collection.size()或collection.contains(...)—— 这些都是 O(n) 操作,嵌套后变成 O(n²)。
大规模数据考虑并行或流式处理
单线程遍历百万级元素已成瓶颈时,可升级策略:
- 纯只读且无状态处理(如日志打印、数值统计),优先用
collection.parallelStream().forEach(...),JVM 自动分段并行,实测 4 核机器下 100 万元素提速约 2.5×;注意:forEach不保证顺序,需顺序用forEachOrdered(略降速)。 - 需要边遍历边修改(如过滤+转换),用
stream().filter().map().collect(...)更安全清晰;避免在 parallelStream 中修改共享变量(如 static 计数器),会导致结果不可预测。 - 极端场景(如实时风控、低延迟计算),可手动分片 +
ForkJoinPool,但开发成本高,建议先压测确认是否真有必要。
特殊需求用对专用迭代器
标准 Iterator 覆盖 90% 场景,但以下情况换更合适的工具:
- 需双向遍历(如回滚校验、滑动窗口),用
ListIterator,它提供previous()和hasPrevious(),比反复重置标准迭代器高效得多。 - 需并发遍历且集合可能被其他线程修改,别用普通
Iterator(会抛ConcurrentModificationException),改用CopyOnWriteArrayList.iterator()或ConcurrentHashMap.keySet().iterator(),它们基于快照或弱一致性设计。 - 大数据量 + 需分割处理(如 MapReduce 风格),用
Spliterator,它是Stream底层基础,支持动态估算大小、可分片、可特性标记(ORDERED/SIZED),比传统迭代器更适合现代并行模型。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











