题目
ArrayList 的遍历方式及注意事项
信息
- 类型:问答
- 难度:⭐
考点
ArrayList遍历,迭代器使用,for-each原理,并发修改异常
快速回答
ArrayList 的主要遍历方式:
- 普通 for 循环:通过索引访问元素
- 增强 for 循环:语法简洁,自动处理迭代
- 迭代器 (Iterator):支持安全的删除操作
关键注意事项:
- 遍历时直接调用
remove()会导致ConcurrentModificationException - 删除元素时应使用迭代器的
remove()方法
1. 遍历方式及代码示例
a) 普通 for 循环:
ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}特点: 可通过索引随机访问元素,适合需要下标操作的场景。
b) 增强 for 循环:
for (String fruit : list) {
System.out.println(fruit);
}原理: 编译器将其转换为迭代器实现(底层调用 iterator()),代码更简洁。
c) 迭代器遍历:
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
}2. 并发修改异常 (ConcurrentModificationException)
错误示例:
// 错误!会抛出 ConcurrentModificationException
for (String fruit : list) {
if (fruit.equals("Banana")) {
list.remove(fruit); // 直接调用集合的 remove()
}
}原因: ArrayList 内部维护 modCount(修改计数器)。当迭代器创建后,检测到 modCount 意外变化时抛出异常。
3. 安全删除元素的最佳实践
使用迭代器的 remove() 方法:
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
if (fruit.equals("Banana")) {
iterator.remove(); // 安全删除
}
}原理: 迭代器的 remove() 会同步更新迭代器的状态和集合的 modCount,避免不一致。
4. 常见错误
- 在增强 for 循环中修改集合:直接调用
add()/remove()导致异常 - 多次调用
iterator.next():未配合hasNext()使用可能引发NoSuchElementException
5. 扩展知识
- ListIterator:支持双向遍历和添加/修改元素
- Java 8+ 的 forEach:
list.forEach(System.out::println) - 线程安全替代方案:需并发修改时使用
CopyOnWriteArrayList