当前位置: 首页 > news >正文

什么是 Java 中的迭代器(Iterator)?

Java 中的迭代器(Iterator)是一种设计模式,用于遍历集合中的元素,而不需要暴露集合的内部结构。它是 Java 集合框架的核心组件之一。

基本概念

Iterator 接口

Iterator是一个接口,位于java.util包中,提供了统一的方式来遍历各种集合。

publicinterfaceIterator<E>{booleanhasNext();// 判断是否还有下一个元素Enext();// 返回下一个元素defaultvoidremove(){}// 删除当前元素(可选操作)defaultvoidforEachRemaining(Consumer<?superE>action){}// Java 8 新增}

基本用法

1.创建和使用迭代器

List<String>names=Arrays.asList("张三","李四","王五");// 获取迭代器Iterator<String>iterator=names.iterator();// 遍历元素while(iterator.hasNext()){Stringname=iterator.next();System.out.println(name);}

2.for-each 循环(语法糖)

List<String>names=Arrays.asList("张三","李四","王五");// for-each 循环内部使用迭代器for(Stringname:names){System.out.println(name);}// 等价于上面的 while 循环

主要方法详解

1.hasNext() 和 next()

List<Integer>numbers=Arrays.asList(1,2,3,4,5);Iterator<Integer>iterator=numbers.iterator();while(iterator.hasNext()){Integernum=iterator.next();System.out.println("当前元素: "+num);System.out.println("是否还有下一个: "+iterator.hasNext());}

2.remove() 方法

List<String>names=newArrayList<>(Arrays.asList("张三","李四","王五","赵六"));Iterator<String>iterator=names.iterator();while(iterator.hasNext()){Stringname=iterator.next();if(name.equals("李四")){iterator.remove();// 安全删除当前元素}}System.out.println(names);// [张三, 王五, 赵六]

重要注意事项:

  • remove()必须在调用next()之后调用
  • 每次调用next()只能调用一次remove()
  • 不是所有集合都支持remove()操作

3.forEachRemaining() 方法(Java 8+)

List<String>names=Arrays.asList("张三","李四","王五");Iterator<String>iterator=names.iterator();// 先跳过第一个元素if(iterator.hasNext()){iterator.next();}// 处理剩余元素iterator.forEachRemaining(name->System.out.println("剩余: "+name));

迭代器 vs 其他遍历方式

1.传统 for 循环

List<String>names=Arrays.asList("张三","李四","王五");// 传统 for 循环for(inti=0;i<names.size();i++){Stringname=names.get(i);System.out.println(name);}// 优点:可以访问索引// 缺点:代码冗长,只适用于 List

2.for-each 循环

List<String>names=Arrays.asList("张三","李四","王五");// for-each 循环for(Stringname:names){System.out.println(name);}// 优点:简洁,适用于所有集合// 缺点:无法在遍历中删除元素

3.迭代器

List<String>names=Arrays.asList("张三","李四","王五");// 迭代器Iterator<String>iterator=names.iterator();while(iterator.hasNext()){Stringname=iterator.next();if(name.equals("李四")){iterator.remove();// 可以安全删除}}// 优点:可以安全删除元素,适用于所有集合// 缺点:代码相对冗长

ListIterator

ListIteratorIterator的子接口,专门用于 List 集合,提供了双向遍历功能。

List<String>names=newArrayList<>(Arrays.asList("张三","李四","王五"));ListIterator<String>listIterator=names.listIterator();// 正向遍历System.out.println("正向遍历:");while(listIterator.hasNext()){intindex=listIterator.nextIndex();Stringname=listIterator.next();System.out.println(index+": "+name);}// 反向遍历System.out.println("反向遍历:");while(listIterator.hasPrevious()){intindex=listIterator.previousIndex();Stringname=listIterator.previous();System.out.println(index+": "+name);}// 添加元素listIterator.add("新元素");// 修改元素if(listIterator.hasNext()){listIterator.next();listIterator.set("修改后的元素");}

实际应用场景

1.安全删除元素

List<Integer>numbers=newArrayList<>(Arrays.asList(1,2,3,4,5,6,7,8,9,10));// 删除偶数Iterator<Integer>iterator=numbers.iterator();while(iterator.hasNext()){Integernum=iterator.next();if(num%2==0){iterator.remove();// 安全删除}}System.out.println(numbers);// [1, 3, 5, 7, 9]

2.过滤集合

List<String>names=newArrayList<>(Arrays.asList("张三","李四","王五","赵六","钱七"));// 删除名字长度为2的元素Iterator<String>iterator=names.iterator();while(iterator.hasNext()){Stringname=iterator.next();if(name.length()==2){iterator.remove();}}System.out.println(names);// [张三, 李四, 王五, 赵六, 钱七](假设都是2个字)

3.自定义迭代器

publicclassRangeimplementsIterable<Integer>{privateintstart;privateintend;publicRange(intstart,intend){this.start=start;this.end=end;}@OverridepublicIterator<Integer>iterator(){returnnewIterator<Integer>(){privateintcurrent=start;@OverridepublicbooleanhasNext(){returncurrent<=end;}@OverridepublicIntegernext(){if(!hasNext()){thrownewNoSuchElementException();}returncurrent++;}};}}// 使用自定义迭代器Rangerange=newRange(1,5);for(intnum:range){System.out.println(num);// 1, 2, 3, 4, 5}

4.处理嵌套集合

List<List<String>>nestedList=Arrays.asList(Arrays.asList("A","B","C"),Arrays.asList("D","E"),Arrays.asList("F","G","H","I"));// 使用迭代器处理嵌套结构Iterator<List<String>>outerIterator=nestedList.iterator();while(outerIterator.hasNext()){List<String>innerList=outerIterator.next();Iterator<String>innerIterator=innerList.iterator();while(innerIterator.hasNext()){Stringelement=innerIterator.next();System.out.print(element+" ");}System.out.println();}

并发修改异常

问题示例

List<String>names=newArrayList<>(Arrays.asList("张三","李四","王五"));// 错误:在遍历时直接修改集合for(Stringname:names){if(name.equals("李四")){names.remove(name);// ConcurrentModificationException}}

正确做法

List<String>names=newArrayList<>(Arrays.asList("张三","李四","王五"));// 正确:使用迭代器删除Iterator<String>iterator=names.iterator();while(iterator.hasNext()){Stringname=iterator.next();if(name.equals("李四")){iterator.remove();// 安全删除}}

Java 8+ 的替代方案

1.Stream API

List<String>names=newArrayList<>(Arrays.asList("张三","李四","王五","赵六"));// 使用 Stream 过滤List<String>filtered=names.stream().filter(name->!name.equals("李四")).collect(Collectors.toList());System.out.println(filtered);// [张三, 王五, 赵六]

2.removeIf 方法

List<String>names=newArrayList<>(Arrays.asList("张三","李四","王五","赵六"));// 使用 removeIfnames.removeIf(name->name.equals("李四"));System.out.println(names);// [张三, 王五, 赵六]

3.forEach 方法

List<String>names=Arrays.asList("张三","李四","王五");// 使用 forEachnames.forEach(name->System.out.println(name));// 使用方法引用names.forEach(System.out::println);

性能考虑

1.不同遍历方式的性能

List<Integer>largeList=newArrayList<>();for(inti=0;i<1000000;i++){largeList.add(i);}// 传统 for 循环(最快)longstart=System.currentTimeMillis();for(inti=0;i<largeList.size();i++){Integernum=largeList.get(i);}System.out.println("传统 for: "+(System.currentTimeMillis()-start)+"ms");// 迭代器(中等)start=System.currentTimeMillis();Iterator<Integer>iterator=largeList.iterator();while(iterator.hasNext()){Integernum=iterator.next();}System.out.println("迭代器: "+(System.currentTimeMillis()-start)+"ms");// for-each(与迭代器类似)start=System.currentTimeMillis();for(Integernum:largeList){// 使用 num}System.out.println("for-each: "+(System.currentTimeMillis()-start)+"ms");

最佳实践

✅ 推荐做法

// 1. 简单遍历使用 for-eachList<String>names=Arrays.asList("张三","李四","王五");for(Stringname:names){System.out.println(name);}// 2. 需要删除元素时使用迭代器Iterator<String>iterator=names.iterator();while(iterator.hasNext()){Stringname=iterator.next();if(shouldRemove(name)){iterator.remove();}}// 3. Java 8+ 优先使用 Stream 或 removeIfnames.removeIf(name->shouldRemove(name));// 4. 需要索引时使用传统 for 循环for(inti=0;i<names.size();i++){System.out.println(i+": "+names.get(i));}

❌ 避免的做法

// 1. 避免在 for-each 中删除元素for(Stringname:names){names.remove(name);// ConcurrentModificationException}// 2. 避免多次调用 next() 而不检查 hasNext()Iterator<String>iterator=names.iterator();Stringname1=iterator.next();Stringname2=iterator.next();// 可能抛出 NoSuchElementException// 3. 避免在不需要时使用迭代器// 简单遍历不需要迭代器的复杂性

总结

Java 迭代器的主要特点:

  • 统一接口:为所有集合提供统一的遍历方式
  • 安全删除:可以在遍历过程中安全删除元素
  • 封装性:不暴露集合的内部结构
  • 灵活性:支持自定义迭代逻辑
  • 向后兼容:支持旧版本的集合操作

迭代器是 Java 集合框架的重要组件,理解它有助于更好地处理集合遍历和修改操作。在现代 Java 中,虽然 Stream API 提供了更强大的功能,但迭代器仍然是处理某些场景的重要工具。

http://www.jsqmd.com/news/403321/

相关文章:

  • 光储直流微电网附Simulink仿真
  • 什么是 Java 的网络编程?
  • 【开题答辩全过程】以 高校学生档案管理系统为例,包含答辩的问题和答案
  • 大模型搜索引爆营销新赛道,智跑AI以GEO系统引领智能获客潮流
  • Java 中的基本数据类型有哪些?
  • 基于ARIMA-CNN-LSTM预测模型研究附Python代码
  • D证-科目一
  • 官网-劳动人事争议仲裁办案规则
  • Java 的 I/O 流是什么?
  • 航天器交会的分布式MPC模型预测控制研究附Matlab代码
  • Java 的 Optional 类是什么?它有什么用?
  • 如果一个线程在 Java 中被两次调用 start() 方法,会发生什么?
  • 图论——最短路Dijkstra算法
  • 2026年保健品推荐:品质与口碑并存,养胃颗粒/保健饮品/保健品,保健品品牌有哪些 - 品牌推荐师
  • [NOI2018] 冒泡排序
  • 通过MATLAB控制COMSOL Multiphysisc仿真进程模拟局部放电,建立有限元仿真模型
  • 【GLM-5 陪练式前端新手入门】第四篇:卡片布局 —— 让个人主页内容更有层次
  • Splay进阶
  • 【GLM-5 陪练式前端新手入门】第三篇:网页导航栏 —— 搭建个人主页的 “指路牌”
  • [AI提效-17]-豆包图片生成功能新手入门指南
  • 写一个自动检测照片光线构图,给出优化建议,颠覆拍照全靠盲拍。
  • Python基于Vue的 古城景区管理系统的设计与实现django flask pycharm
  • 视频孪生平台之上:镜像视界三维实时解算体系在危化园区风险半径动态解算中的全球领先性研究
  • 2134523
  • 5784784
  • 深度解读:Android开发工程师岗位核心能力与技术进阶之路——以苏州池久节能电气有限公司职位要求为例
  • 苏州智观易盛信息科技有限公司 Android 开发工程师职位深度解析与面试全攻略
  • AI 2.0提示工程架构师:提示词调试与优化的9个实用工具
  • 大数据领域日志数据压缩算法的比较与选择
  • Zookeeper为大数据领域分布式计算带来的优势