1. Java遍历方法全景解析
在Java开发中,遍历集合是最基础却最频繁的操作之一。不同的遍历方式各有特点,就像工具箱里的不同工具,用对了事半功倍,用错了可能引发性能问题甚至bug。作为从业十年的Java开发者,我整理了六种主流遍历方式的实现原理、适用场景和避坑指南。
1.1 基础遍历三剑客
普通for循环是最原始的遍历方式,相当于拿着清单按编号取货:
java复制for (int i = 0; i < list.size(); i++) {
Item item = list.get(i);
}
注意:ArrayList的get(i)是O(1)操作,但LinkedList的get(i)是O(n)操作。我曾在一个百万级LinkedList上使用普通for循环,导致接口响应从200ms暴增到15秒。
增强for循环(for-each)是语法糖,编译后实际转换为Iterator实现:
java复制for (Item item : collection) {
// 处理item
}
底层原理是通过调用集合的iterator()方法获取迭代器。在JDK5引入后,已成为最常用的遍历方式。
Iterator迭代器提供了安全的遍历-删除操作:
java复制Iterator<Item> it = collection.iterator();
while (it.hasNext()) {
Item item = it.next();
if (needRemove(item)) {
it.remove(); // 唯一安全的遍历时删除方式
}
}
在并发修改场景下,其他遍历方式会抛出ConcurrentModificationException,而Iterator的remove()方法通过维护expectedModCount实现安全删除。
1.2 高级遍历方案
ListIterator是Iterator的增强版,专为List设计:
java复制ListIterator<Item> lit = list.listIterator();
while (lit.hasNext()) {
Item item = lit.next();
if (needInsertBefore(item)) {
lit.previous(); // 回退
lit.add(newItem); // 插入
}
}
特别适合需要双向遍历或中间插入的场景。我在实现文本编辑器时就用它来处理行级操作。
forEach+Lambda是JDK8引入的函数式风格:
java复制list.forEach(item -> process(item));
简洁但功能有限,无法使用break/return控制流程。在简单的日志打印等场景非常适用。
Stream API提供了声明式处理能力:
java复制list.stream()
.filter(item -> item.isValid())
.m
