Iterator 迭代器、ListIterator & foreach 循环

一、Iterator 迭代器接口

1. 基础说明

  • 包:java.util.Iterator,使用前需要导入
  • 作用:通用遍历 Collection 集合,依靠指针(游标)跟踪元素
  • 游标初始位置:第一个元素的前面
  • 泛型说明:不写泛型时,取出元素默认是Object类型,需要强制类型转换;推荐使用泛型,避免强转

2. 核心方法

方法 功能描述
boolean hasNext() 判断游标后面是否还有下一个元素;只判断,不移动指针
E next() 返回下一个元素,同时将指针向后移动一位
void remove() 删除迭代器最后访问到的元素(迭代器自带删除)

遍历流程(课件图示顺序) ① hasNext () 判断有元素 → ② next () 取值 + 指针后移 ③ hasNext () 判断有元素 → ④ next () 取值 + 指针后移 ⑤ hasNext () 判断有元素 → ⑥ next () 取值 + 指针后移 ⑦ hasNext () 判断无元素,循环结束

3. 基础代码示例

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

public class TestIterator {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");

        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            String s = it.next();
            System.out.println(s);
        }
    }
}

4. 重点:并发修改异常 ConcurrentModificationException

✅ 课件要点:迭代器遍历期间,如果调用**集合对象自己的 remove ()/add ()**修改集合长度,继续遍历就抛出并发修改异常

  • 错误写法(集合 remove)

    while (it.hasNext()){
    String s = it.next();
    if("李四".equals(s)){
    list.remove(s); // ❌ 集合方法,报异常
    }
    }

  • 正确写法(迭代器自带 remove)

    while (it.hasNext()){
    String s = it.next();
    if("李四".equals(s)){
    it.remove(); // ✅ 迭代器删除,安全
    }
    }

原理:集合维护modCount修改计数器,迭代器记录初始值expectedModCount,两者不一致触发异常。

5. Iterator 局限

只能单向向后遍历;没有添加、替换元素的方法;只能用于 Collection。


二、ListIterator(List 专属迭代器,Iterator 的子接口)

只用于 List 集合,功能比普通 Iterator 更强,支持双向遍历、增删改、获取索引

1. 主要特性

  1. 双向遍历:可以向前、向后遍历
  2. 修改能力:遍历中添加、删除、替换元素
  3. 索引支持:可以获取当前元素对应索引

2. 全套方法表

方法 描述
next() 返回下一个元素,光标后移
previous() 返回前一个元素,光标前移
hasNext() 判断是否存在下一个元素
hasPrevious() 判断是否存在前一个元素
nextIndex() 返回下一个元素的索引
previousIndex() 返回前一个元素的索引
remove() 删除光标前的元素
set(E e) 替换光标前的元素
add(E e) 在光标当前位置插入元素

3. 简单示例(反向遍历)

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

public class TestListIterator {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");

        ListIterator<String> lit = list.listIterator();
        // 先走到末尾
        while (lit.hasNext()){
            lit.next();
        }
        // 反向遍历
        while (lit.hasPrevious()){
            System.out.println(lit.previous());
        }
    }
}

三、foreach 循环(增强 for 循环)

1. 基础介绍

foreach 是简化版 for 循环,底层依然是 Iterator 迭代器(语法糖) 适用范围:数组、所有实现Iterable的 Collection 集合 语法格式:

复制代码
for(容器中元素类型 临时变量 : 容器变量) {
    执行语句
}

示例:

复制代码
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
for(String s : list){
    System.out.println(s);
}

int[] arr = {1,2,3};
for(int num : arr){
    System.out.println(num);
}

2. 课件重点缺陷

foreach 循环只能访问元素,不能修改集合结构(增删);循环里的临时变量是元素副本:

  • 修改临时变量,不会改变原集合 / 数组里面的值
  • 遍历途中调用集合 add/remove → 并发修改异常
  • 没有索引,不知道当前遍历位置

四、四种遍历方式汇总对比(Iterator / ListIterator / 增强 for / Lambda forEach)

遍历方式 底层 方向 增删改 是否有索引 适用场景
Iterator 迭代器 单向向后 ✅ it.remove() ❌ 通用 Collection,遍历中删除
ListIterator List 专属迭代器 双向 ✅ add/remove/set ✅ List 集合,反向遍历、边遍历边修改
增强 for foreach Iterator 语法糖 单向向后 ❌ 不能增删集合 ❌ 单纯遍历,代码简洁
集合.forEach (Lambda) 函数式接口 单向 ❌ 不能增删集合 ❌ JDK8+,简洁对每个元素执行操作

五、易错点总结

  1. hasNext()只判断,不移动指针;不能连续多次调用next(),容易NoSuchElementException
  2. 泛型缺失时,Iterator 取出元素是 Object,需要强制转换
  3. ListIterator只能 List 获取,Set 集合不能使用
  4. 增强 for 只是语法糖,编译后依然变成 Iterator,同样不能在遍历时直接调用集合增删方法
相关推荐
樱花落木兰1 小时前
Redis 消息队列的可靠性演进:从 List、Pub/Sub 到 Stream 消费者组,以及 8.x 版本改变了什么
java·开发语言·经验分享·redis·分布式·python·软件工程
外收内放1 小时前
ENSP学习记录(6)
开发语言·学习·php
dialect_1 小时前
CODEFORCES ROUND 1127 DIV2
开发语言·c++·算法
盛世宏博北京1 小时前
档案库房恒温恒湿消毒净化一体机与3D可视化平台联动调试笔记
开发语言·php·温湿度·档案室
小徐不徐说10 小时前
序列化与反序列化:把 C++ 对象可靠地保存下来
开发语言·数据库·c++·php
ragnwang10 小时前
Notes: Python pybind11 import C++ module
开发语言·c++·python
Wang's Blog10 小时前
Java 项目实战: 交友项目 - 搜索附近的功能概述和分析
java·开发语言·交友
骑着蜗牛撵大象32711 小时前
大模型 Agent 的沙箱护栏:gVisor 隔离、出口白名单与审计闭环
java·开发语言·jvm·安全·agent沙箱·gvisor·microvm
Dxy123931021612 小时前
JS DES 加密详解
开发语言·javascript·arcgis