Java 迭代器(Iterator)完全指南:从入门到实战

一、什么是迭代器?

迭代器是 Java 集合框架中的一种设计模式 ,它的核心作用是:提供一种统一的方式遍历集合中的元素,而不需要暴露集合内部的实现细节

你可以把它想象成一个"游标":

  • 一开始指向集合的第一个元素之前
  • 通过调用方法可以逐个移动游标并获取元素
  • 遍历完成后游标指向集合末尾

二、入门级讲解:基本用法

1. 核心接口定义

Java 中所有迭代器都实现了 java.util.Iterator 接口,核心方法只有三个:

java 复制代码
public interface Iterator<E> {
    // 判断是否还有下一个元素
    boolean hasNext();
    // 获取下一个元素(调用前必须先判断hasNext())
    E next();
    // 删除当前迭代到的元素(可选操作)
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
}
2. 最简单的遍历示例

以最常用的 ArrayList 为例,演示基础遍历流程:

java 复制代码
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorBasicDemo {
    public static void main(String[] args) {
        List<String> fruits = new ArrayList<>();
        fruits.add("苹果");
        fruits.add("香蕉");
        fruits.add("橙子");

        // 1. 获取迭代器
        Iterator<String> iterator = fruits.iterator();

        // 2. 遍历集合
        while (iterator.hasNext()) {
            String fruit = iterator.next();
            System.out.println("当前水果:" + fruit);

            // 可选:删除符合条件的元素(注意不能用集合的remove方法)
            if ("香蕉".equals(fruit)) {
                iterator.remove();
            }
        }

        System.out.println("删除香蕉后的集合:" + fruits);
    }
}

运行结果:

复制代码
当前水果:苹果
当前水果:香蕉
当前水果:橙子
删除香蕉后的集合:[苹果, 橙子]

三、实战进阶:实用场景与避坑指南

1. 遍历中安全删除元素

⚠️ 关键注意点 :在迭代过程中,不能直接调用集合的 remove() 方法,否则会抛出 ConcurrentModificationException 并发修改异常。必须使用迭代器自身的 remove() 方法。

错误示例:

java 复制代码
// 错误写法:遍历中直接修改集合
for (String fruit : fruits) {
    if ("香蕉".equals(fruit)) {
        fruits.remove(fruit); // 会抛出异常
    }
}
2. 增强 for 循环与迭代器的关系

Java 的增强 for 循环(for-each)本质上是迭代器的语法糖,编译后会自动转换成迭代器遍历:

java 复制代码
// 等价于上面的迭代器写法
for (String fruit : fruits) {
    System.out.println(fruit);
}
3. 反向迭代器:ListIterator

对于有序集合(如 ArrayList),可以使用 ListIterator 实现双向遍历

java 复制代码
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListIteratorDemo {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);

        // 获取从末尾开始的迭代器
        ListIterator<Integer> iterator = numbers.listIterator(numbers.size());

        // 反向遍历
        while (iterator.hasPrevious()) {
            Integer num = iterator.previous();
            System.out.println("反向遍历:" + num);
        }
    }
}

运行结果:

复制代码
反向遍历:3
反向遍历:2
反向遍历:1
4. 迭代器的应用场景
  • 遍历各种集合(List、Set、Map 的 entrySet/keySet 等)
  • 在遍历中安全删除元素
  • 统一不同集合的遍历方式(不管是 ArrayList 还是 HashSet,都用同样的迭代器接口)

四、优缺点与特点总结

特性 详细说明
优点 1. 统一遍历接口,无需关心集合内部实现 2. 遍历中安全删除元素 3. 支持单向/双向遍历(ListIterator) 4. 解耦集合与遍历逻辑
缺点 1. 只能单向遍历(普通 Iterator),不能随机访问 2. 遍历过程中不能修改集合(除了迭代器自身的 remove 方法 ) 3. 比普通 for 循环(基于索引)的性能略低(对 ArrayList 这类随机访问集合)
🎯 核心特点 1. 迭代器是一次性的 :遍历完成后需要重新获取才能再次遍历 2. 快速失败(Fail-Fast)机制:如果在迭代过程中集合被修改,会立即抛出异常

五、类似遍历方式对比

遍历方式 适用场景 性能 可修改性
迭代器 Iterator 所有集合类型,需要在遍历中删除元素 中等(LinkedList 比索引遍历快) 仅支持迭代器的 remove()
增强 for 循环 仅需要读取元素,不需要修改 与迭代器一致 不能修改集合
普通 for 循环(索引) 仅支持有序集合(List),需要随机访问 对 ArrayList 最快 可以直接修改集合,但遍历中删除会导致元素索引混乱
forEach() 方法(Java 8+) 函数式编程风格,仅读取元素 与迭代器一致 不能修改集合(会抛出异常)
对比示例:
java 复制代码
// 1. 普通索引遍历(仅适用于List)
for (int i = 0; i < fruits.size(); i++) {
    System.out.println(fruits.get(i));
}

// 2. Java 8+ forEach 方法
fruits.forEach(fruit -> System.out.println(fruit));
相关推荐
我是一颗柠檬8 分钟前
【Java项目技术亮点】加权轮询负载均衡算法
java·算法·负载均衡
灯厂码农14 分钟前
C语言动态内存分配完全指南(malloc、calloc、realloc、free)
java·c语言·算法
yoothey19 分钟前
报废审批流规则引擎设计——责任链模式完整实现
linux·开发语言·bash
geovindu36 分钟前
python: Functional Options Pattern
开发语言·后端·python·设计模式·惯用法模式·函数式选项模式
wuyk55543 分钟前
24. C 语言模块化:不是拆几个.c 文件那么简单
c语言·开发语言·stm32·单片机
梦梦代码精1 小时前
电商系统不是技术堆叠:LikeShop如何用分层Hold住复杂业务?
java·docker·代码规范
凯瑟琳.奥古斯特1 小时前
K次取反最大化数组和解法(力扣1005)
开发语言·c++·算法·leetcode·职场和发展
负责的蛋挞1 小时前
异步HttpModule的实现方式
java·服务器·前端
AC赳赳老秦2 小时前
防火墙规则批量配置实战:OpenClaw 自动生成模板、批量下发与合规性校验全解析
java·开发语言·人工智能·python·github·php·openclaw
☆cwlulu2 小时前
调试排查工具介绍(gdb、strace、Valgrind等)
开发语言·c++·嵌入式硬件·ubuntu