补充学习 Iterator

Iterator(迭代器)是 Java 集合框架中的一个核心接口,位于 java.util 包下。

你可以把它想象成一个“游标”或“检查员”。它的主要作用是让你能够统一地、顺序地访问集合(如 List, Set)中的元素,而无需关心集合底层是如何存储数据的(是数组还是链表)。

1. 核心方法

Iterator 接口主要定义了三个方法,构成了遍历的基础:

方法描述
hasNext()返回 boolean。检查集合中是否还有下一个元素(就像问“还有下一站吗?”)。
next()返回集合中的下一个元素,并将游标向后移动一位。
remove()(重点) 从集合中移除 next() 方法返回的最后一个元素。这是在遍历过程中唯一安全的删除方式。

2. 为什么要用 Iterator?(核心价值)

统一遍历方式

无论底层是 ArrayList(数组结构)、LinkedList(链表结构)还是 HashSet(哈希结构),你都可以使用同一套代码(while(it.hasNext())...)来遍历。这体现了多态和解耦的设计思想。

安全地删除元素(面试高频)

这是 Iterator 最实用的场景。如果你在遍历集合时,直接使用集合自身的 remove() 方法(例如 list.remove()),程序会抛出异常。而使用 iterator.remove() 则是安全的。

错误示范(会抛出异常):

for (String s : list) {
    if (s.equals("B")) {
        list.remove(s); // ❌ 抛出 ConcurrentModificationException
    }
}

正确示范:

Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s.equals("B")) {
        it.remove(); // ✅ 安全删除,不会报错
    }
}

3. 核心机制:Fail-Fast(快速失败)

这是 Iterator 的一个重要特性,也是新手常遇到的坑。

  • 现象: 当你在使用 Iterator 遍历集合时,如果集合的结构被非迭代器的方式修改了(比如你用 list.add() 或 list.remove()),Iterator 会立即抛出 ConcurrentModificationException 异常。
  • 原理: 集合内部维护了一个 modCount(修改次数)变量。Iterator 在创建时会记录这个值(expectedModCount)。每次调用 next() 时,Iterator 都会检查这两个值是否一致。如果不一致,说明集合被“偷偷”修改了,为了防止数据不一致,它直接报错。
  • 目的: 这不是为了线程安全,而是为了尽早暴露错误,防止程序在数据混乱的状态下继续运行。

4. 扩展:ListIterator

普通的 Iterator 只能从头往后遍历(单向)。如果你需要双向遍历(向前或向后),或者需要在遍历过程中添加/修改元素,可以使用 ListIterator(仅适用于 List 集合)。

  • hasPrevious() / previous():支持反向遍历。
  • add() / set():支持在遍历中修改集合。

5. 总结对比

为了方便记忆,我为你整理了一个对比表:

特性IteratorListIterator
适用集合所有 Collection (List, Set, Queue)仅限 List (ArrayList, LinkedList)
遍历方向单向(只能向后)双向(向前、向后)
修改操作仅支持 remove()支持 remove(), add(), set()
主要用途通用遍历、安全删除复杂列表操作、反向遍历
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐