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

数据结构(Java):迭代器遍历【底层源码解析】

1、引言

我们知道,对于List系列集合,添加的元素是有序、可重复、有索引的;而对于Set系列集合,添加的元素是无序、不重复、无索引的。

那么使用for循环通过下标来对Set系列集合进行遍历,那显然是不行的。

迭代器就可以解决这个问题。

因为迭代器迭代器不依赖索引,故既能对有索引集合进行遍历,又能对无索引集合进行遍历。

迭代器也是集合专用的遍历方式。

2、迭代器遍历

迭代器遍历的原理就是:从下标0的位置开始,一个元素一个元素的向后遍历,直到遍历结束。

注意:迭代器不依赖索引

代码如下:

public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");//获取迭代器对象Iterator<String> it = list.iterator();while (it.hasNext()) {//判断当前位置是否有元素String str = it.next();//1.获取当前位置 2.将迭代器指针指向下一个元素System.out.println(str);}}

我先对其中的方法做一下简单说明。

2.1 获取迭代器对象

使用迭代器进行遍历,我们首先需要获取迭代器对象,而我们可以调用ArrayList中的iterator方法来获取迭代器对象。

我们通过源码可以发现,返回值为Iterator<E>,我们使用Iterator<E>接收即可。

2.2 迭代器的方法

2.2.1 hasNext方法

该方法就是判断,当前迭代器对象指向的位置上是否有元素,若有元素,则返回true,若没有元素,则返回false。

2.2.2 next方法

该方法有两个步骤:

1.获取当前位置上的元素

2.迭代器指针往后移动,指向下一个元素


到目前为止,想要使用迭代器来进行遍历,以上的三种方法是我们必须要掌握的:

1.iterator方法:获取迭代器对象

2.hasNext方法:判断当前位置是否有元素

3.Next方法:获取当前位置元素并且迭代器指针向后移动


2.3 迭代器的四个细节

2.3.1 细节点1

如果当前位置没有元素,还使用next方法进行获取,会抛出NoSuchElementException异常

2.3.2 细节点2

迭代器遍历完毕,指针不会复位

2.3.3 细节点3

循环中只能用一次next方法

因为每使用一次next方法,指针就会向后移动一次;若循环中有两个next方法,而元素个数为奇数个时,则会一次循环指针移动两次,最后一次循环时,会有一个next获取元素时当前位置没有元素,会抛出NoSuchElementException异常。

2.3.4 细节点4

迭代器遍历时,不能使用集合的方法进行增加或删除元素

例如:

若在迭代器遍历时使用了集合的增加或者删除方法,会抛出ConcurrentModificationException(并发修改异常)

至于为什么不能使用集合的方法来修改元素,我将在下面的源码分析中解释。

所以,如果想要在迭代器遍历时修改元素,我们使用迭代器的相关方法即可:

代码:

public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String str = iterator.next();if ("aaa".equals(str)) {//迭代器遍历时,删除元素,只能使用迭代器的remove方法iterator.remove();}}System.out.println(list);}

如果要删除元素,使用迭代器的remove方法;

如果要添加元素,暂时还没有方法。


OK,迭代器遍历的大致内容已经阐述完毕,接下来是迭代器源码的深度解析


2.4 迭代器遍历 源码深度解析

我已经将底层源码分析整理在这张图上,清晰明了:

OK~本次博客到这里就结束了,

感谢大家的阅读~欢迎大家在评论区交流问题~

如果博客出现错误可以提在评论区~

创作不易,请大家多多支持~

相关文章:

  • 2024年高校辅导员考试题库及答案
  • c#上位机与PLC通讯心跳的实现方法
  • Go内存回收
  • Python获取QQ音乐歌单歌曲
  • 数据特征采样在 MySQL 同步一致性校验中的实践
  • 计算机未来大方向的选择
  • MViT(ICCV 2021, Meta)论文解读
  • 阶段三:项目开发---大数据系统基础环境准备:任务1:准备系统运行的先决条件
  • vue项目创建+eslint+Prettier+git提交规范(commitizen+hooks+husk)
  • React
  • 开始尝试从0写一个项目--后端(一)
  • 6.8应用进程跨网络通信
  • Airflow: 大数据调度工具详解
  • 0/1背包问题总结
  • 【Python机器学习】处理文本数据——将文本数据表示为词袋
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • Android单元测试 - 几个重要问题
  • echarts的各种常用效果展示
  • eclipse(luna)创建web工程
  • happypack两次报错的问题
  • Java 内存分配及垃圾回收机制初探
  • Javascript基础之Array数组API
  • JS笔记四:作用域、变量(函数)提升
  • PHP 7 修改了什么呢 -- 2
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • tensorflow学习笔记3——MNIST应用篇
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • Vim Clutch | 面向脚踏板编程……
  • 从0实现一个tiny react(三)生命周期
  • 基于Android乐音识别(2)
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 记一次删除Git记录中的大文件的过程
  • 力扣(LeetCode)22
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • # 数论-逆元
  • #{}和${}的区别?
  • #pragma pack(1)
  • (1)(1.11) SiK Radio v2(一)
  • (Matlab)使用竞争神经网络实现数据聚类
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • .net core 连接数据库,通过数据库生成Modell
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .net项目IIS、VS 附加进程调试
  • 。Net下Windows服务程序开发疑惑
  • ::前边啥也没有