Java基础面试题03:简述什么是迭代器(Iterator)?

时间:2024-11-27 14:05:49

面试题:简述什么是迭代器(Iterator)?

一、什么是Iterator?

迭代器(Iterator)是一个专门用来遍历集合(如数组、列表等)中的元素的对象。它可以帮助开发者按照一定的规则顺序访问集合中的每一个元素,而无需了解集合内部的实现细节。可以简单理解为迭代器是一个“导航员”,负责帮你从头到尾“走遍”整个集合。

为什么需要迭代器?

在迭代器出现之前,我们通常是直接使用集合的内部结构进行遍历,例如:

1. 使用数组
int[] arrays = new int[10];
for (int i = 0; i < arrays.length; i++) {
    int a = arrays[i];
    // 处理元素
}
2. 使用列表(如 ArrayList)
List<String> list = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
    String string = list.get(i);
    // 处理元素
}

这种方式的问题在于:

  • 遍历逻辑和集合结构绑定得很紧密,耦合性高。
  • 每种集合(如数组、列表)需要使用不同的遍历方式,代码难以复用。
  • 如果集合类型发生变化(例如从 ArrayList 切换为 LinkedList),还需要修改遍历代码,非常麻烦。

**为了解决这些问题,Iterator 应运而生。**它提供了一种统一的遍历逻辑,屏蔽了集合的内部实现细节。

Iterator 的作用

迭代器通过一些简单的操作(比如“向前”、“取当前元素”等),可以轻松实现对集合的遍历。开发者只需专注于业务逻辑,无需关心集合是如何存储数据的。

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String string = iterator.next();
    // 处理元素
}

二、java.util.Iterator 的基本接口

在 Java 中,Iterator 是一个接口。它定义了对集合进行遍历的基本规则。Iterator 的接口代码如下:

public interface Iterator {
    boolean hasNext(); // 判断是否有下一个元素
    Object next();     // 返回下一个元素
    void remove();     // 删除当前元素
}

方法说明:

  1. boolean hasNext()
    检查集合中是否还有未访问的元素,返回 true 表示还有,false 表示没有了。

  2. Object next()
    返回集合中当前指针指向的元素,并将指针移到下一个位置。如果没有元素了,会抛出 NoSuchElementException

  3. void remove()
    删除最近一次调用 next() 返回的元素。注意,这个方法需要谨慎使用,如果调用顺序不正确(比如连续调用两次 remove()),会抛出 IllegalStateException

三、各集合中 Iterator 的实现

不同集合的 Iterator 实现逻辑可能不同,但使用方式对开发者是透明的。以 ArrayList 为例:

ArrayList 的 Iterator 实现

ArrayList 中,有一个内部类 Itr,它实现了 Iterator 接口。以下是简化后的核心代码:

private class Itr implements Iterator<E> {
    int cursor;       // 当前元素的索引位置
    int lastRet = -1; // 上一个访问元素的索引位置,-1 表示没有

    public boolean hasNext() {
        return cursor != size; // 判断是否还有元素未访问
    }

    public E next() {
        if (cursor >= size) throw new NoSuchElementException();
        return (E) elementData[lastRet = cursor++];
    }

    public void remove() {
        if (lastRet < 0) throw new IllegalStateException();
        ArrayList.this.remove(lastRet);
        cursor = lastRet;
        lastRet = -1;
    }
}

快速失败机制

在 Java 的集合中,有一个机制叫 快速失败(Fail-Fast),它用来检查集合在遍历过程中是否被修改了。如果检测到集合的内容被其他线程或代码修改,就会抛出 ConcurrentModificationException,以防止错误结果。

ArrayList 中,这通过 modCount 实现。当集合被修改时,modCount 会增加。如果 Iterator 遍历过程中发现 modCount 发生了变化,就会抛出异常。

四、ListIterator 的扩展

除了基本的 Iterator,还有一个更强大的迭代器——ListIterator,专门用于 List 类型集合的遍历。与 Iterator 的区别在于,ListIterator 可以:

  • 双向遍历(通过 previous() 方法向前遍历)。
  • 在遍历过程中插入或修改元素。

示例代码:

List<String> list = new ArrayList<>();
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()) {
    String element = listIterator.next();
    listIterator.set(element + "_updated"); // 修改元素
}

五、三种遍历方式对比

1. 使用方式

For 循环
for (int i = 0; i < list.size(); i++) {
    String element = list.get(i);
    // 处理元素
}
For-Each
for (String element : list) {
    // 处理元素
}
Iterator
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String element = iterator.next();
    // 处理元素
}

2. 区别

方式 优点 缺点
For 循环 简单,适合有序集合(如数组) 与集合结构耦合,代码可读性差
For-Each 简洁,避免索引越界问题 无法修改或删除元素
Iterator 解耦、统一遍历逻辑,可删除元素 写法稍复杂

3. 性能对比

  • ArrayList:随机访问快,因此 For 循环效率高。
  • LinkedList:顺序访问快,因此 Iterator 效率更高。

六、总结

迭代器(Iterator)是遍历集合的强大工具。它的主要优点在于:

  1. 解耦遍历逻辑与集合实现,代码更灵活。
  2. 支持删除和修改元素操作。
  3. 适合各种集合类型,包括有序和无序集合。

当你只需要简单遍历时,For-Each 是最简单的选择;但如果需要修改集合或者操作链式结构的集合,Iterator 无疑是最好的工具。

最后说一句(求关注,求赞,别白嫖我)

最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。
这是大佬写的
7701页的BAT大佬写的刷题笔记,让我offer拿到手软

本文,已收录于,我的技术网站 cxykk.com:程序员编程资料站,有大厂完整面经,工作技术,架构师成长之路,等经验分享

求一键三连:点赞、分享、收藏

点赞对我真的非常重要!在线求赞,加个关注我会非常感激!