iterator()java面试题及答案
以下是关于Java迭代器(Iterator)的常见面试题及答案总结,结合核心概念、实现细节与经典陷阱,帮助应对高频考点:
---
一、迭代器基础概念与使用
1. 什么是迭代器?它的核心作用是什么?
- 定义:迭代器是设计模式的一种,用于统一访问集合元素,无需暴露集合内部结构(如数组、链表)。它解耦遍历逻辑与集合实现,提供标准化的遍历接口。
- 核心方法:
| 方法 | 功能 |
|------------|----------------------------------------------------------------------|
| `hasNext()` | 检查是否还有元素,返回布尔值。 |
| `next()` | 返回下一个元素并移动指针;无元素时抛出`NoSuchElementException`。 |
| `remove()` | 删除`next()`返回的元素;需在`next()`后调用,否则抛出异常。 |
2. 为什么推荐使用迭代器遍历集合?
- 解耦性:遍历逻辑独立于集合实现(如ArrayList、HashSet),代码复用性高。
- 安全删除:通过`iterator.remove()`可安全删除元素,避免并发修改异常(ConcurrentModificationException)。
- 统一接口:支持所有实现`Iterable`接口的集合(如List、Set)。
---
二、经典面试题与陷阱
1. 遍历时删除元素的正确方式
```java
List list = new ArrayList<>(Arrays.asList("1", "2", "3"));
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String str = iterator.next();
if (str.equals("2")) {
iterator.remove(); // ✅ 正确:通过迭代器删除
}
}
// 继续遍历
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("4");
```
输出结果:`4`。
原因:
- 第一次遍历时,删除"2"后,集合大小变为2,迭代器指针停留在索引2(`cursor=2`)。
- 第二次调用`hasNext()`时,`cursor != size`(2 != 2)返回`false`,跳过遍历,直接输出"4"。
- 错误做法:直接调用`list.remove("2")`会触发`ConcurrentModificationException`。
2. ConcurrentModificationException的触发条件
- 原因:迭代器通过`modCount`(集合修改次数)和`expectedModCount`(预期修改次数)检测并发修改。
- 示例:
```java
// 错误:直接调用集合的remove()
for (String s : list) {
if (s.equals("2")) {
list.remove(s); // ❌ 抛ConcurrentModificationException
}
}
```
- 解决方案:
- 使用迭代器的`remove()`方法。
- 或改用`ListIterator`的`remove()`(仅适用于List)。
---
三、迭代器实现细节
1. ArrayList与LinkedList迭代器的差异
- ArrayList:
- 底层基于数组,迭代器通过索引访问元素,随机访问快。
- 实现类为`Itr`,`hasNext()`判断`cursor != size`。
- LinkedList:
- 底层基于链表,迭代器通过指针顺序访问,删除元素效率高。
- 实现类为`ListItr`,`hasNext()`判断`nextIndex 。
- 性能建议:
- 频繁随机访问 → 使用ArrayList + for循环。
- 频繁插入/删除 → 使用LinkedList + 迭代器。
2. ListIterator与Iterator的区别
| 特性 | Iterator | ListIterator |
|--------------------|-----------------------------------|---------------------------------------|
| 适用集合 | 所有Collection(如Set、List) | 仅List集合 |
| 遍历方向 | 单向(next) | 双向(next/previous) |
| 修改能力 | 仅支持删除(remove) | 支持修改(set)和插入(add) |
---
四、高级考点
1. for-each循环的底层实现
- for-each循环是语法糖,编译后转换为迭代器遍历:
```java
for (String s : list) { ... }
// 等价于
Iterator it = list.iterator();
while (it.hasNext()) {
String s = it.next();
...
}
```
- 限制:无法在遍历时删除元素(需显式使用迭代器)。
2. 快速失败机制(Fail-Fast)
- 作用:检测迭代过程中集合的结构性修改(如add/remove),立即抛出`ConcurrentModificationException`。
- 原理:
- 集合维护`modCount`记录修改次数,迭代器初始化时记录`expectedModCount`。
- 每次调用`next()`或`hasNext()`时检查两者是否相等。
---
五、总结
掌握迭代器的面试题需重点理解:
1. 安全删除:必须通过迭代器的`remove()`方法。
2. 并发修改异常:直接修改集合结构会触发异常,需依赖迭代器操作。
3. 集合选择:根据操作场景选择ArrayList或LinkedList的迭代器。
4. 底层机制:如`modCount`与`cursor`的工作原理。
> 更多细节可参考原文:[经典迭代器笔试题解析](https://xie.infoq.cn/article/8)、[快速失败机制源码分析](https://www.cnblogs.com/fengzeng/p/14836457.html)。