最常用、最安全的遍历方式是增强for循环或Iterator;只读用增强for(简洁但不能删元素),需删元素或结构修改必须用Iterator;ArrayList可用传统for+get(i),LinkedList禁用以免O(n²)性能陷阱。

Java里遍历 List 最常用、最安全的方式是增强 for 循环或迭代器(Iterator),但具体选哪种,得看你要不要在遍历中删元素、改结构,或者是否在意性能和可读性。
用增强 for 循环(for-each)遍历 List
适合只读场景,代码简洁,底层自动调用 Iterator,但隐藏了迭代器对象,无法在循环中调用 remove()。
- 直接写
for (Type item : list),不能修改集合结构,否则抛ConcurrentModificationException - 不适用于需要索引的场景;如果硬要索引,得额外定义计数器变量,易出错
- 对
ArrayList性能接近传统 for,但对LinkedList更友好(避免反复get(i)的 O(n) 开销)
for (String s : stringList) {
System.out.println(s);
}
用传统 for + get(i) 遍历 ArrayList
仅推荐用于 ArrayList —— 因为它的 get(i) 是 O(1);换成 LinkedList 就是 O(n²),非常慢。
- 必须用
list.size()做边界判断,别写死数字 - 适合需要下标、或需正向/反向交替访问的场景(比如双指针)
- 若遍历中删除元素,必须手动调整索引(如
i--),否则会跳过下一个元素
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
if ("target".equals(s)) {
list.remove(i);
i--; // 删除后补偿索引
}
}
用 Iterator 或 ListIterator 安全删元素
唯一能在遍历中安全删除元素的方式。普通 Iterator 只支持单向,ListIterator 支持双向且能获取索引。
立即学习“Java免费学习笔记(深入)”;
- 必须用
iterator.remove(),不能用list.remove(),否则抛异常 -
ListIterator可以调用nextIndex()/previousIndex(),适合需要插入或双向遍历的逻辑 - 注意:
Iterator是 fail-fast 的,其他线程或代码块并发修改集合仍会触发异常
Iteratorit = list.iterator(); while (it.hasNext()) { String s = it.next(); if ("toRemove".equals(s)) { it.remove(); // 安全删除 } }
用 forEach() + Lambda(Java 8+)
语法最简,但本质仍是内部使用 Iterator,同样不支持遍历中修改集合,且无法 break 或 continue 外层逻辑。
- 适合纯函数式处理:打印、转换、校验等无副作用操作
- 不能抛受检异常(
Exception),除非包装成运行时异常 - 调试时堆栈信息不如传统循环清晰,定位问题稍麻烦
list.forEach(s -> {
if (!s.isEmpty()) {
System.out.println(s.toUpperCase());
}
});
真正容易被忽略的是:不同 List 实现类的遍历成本差异极大。拿 get(i) 遍历 LinkedList,看似写法没问题,实际可能让接口响应慢几倍——这种隐性性能陷阱,光看语法是发现不了的。










