Java中的迭代器

【精】Java中的迭代器

大家好,我是山大,有到了我有一个朋友系列。
最近,山大的一个朋友问迭代器的问题,有感而发,写了这篇浅析。
问:辣系个炎热的夏天,他问我,为什么有了for循环,还要迭代器,为什么…mmmm,
答:这种问题怎么从你嘴里说出来,咳咳,编不下去了
本章目标
了解什么是迭代器,知道java中迭代器的使用和原理,增强for循环底层与实现。

迭代器的概念

在进入正题之前,我们先聊了解一下什么是迭代:
迭代的概念:
百度百科是这样描述的:
迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。

重复执行一系列运算步骤,从前面的量依次求出后面的量的过程。此过程的每一次结果,都是由对前一次所得结果施行相同的运算步骤得到的。例如利用迭代法*求某一数学问题的解。

对计算机特定程序中需要反复执行的子程序*(一组指令),进行一次重复,即重复执行程序中的循环,直到满足某条件为止,亦称为迭代。

可以这么说,在java中迭代器中迭代就是重复获取集合中的元素,直到满足条件位置。如何获取,如何判断条件,就是方法了。

开发中:
我们都知道,Connection(所有单列集合的父接口),Set和List两个接口继承的就是Connection,开发中,经常需要遍历Connection集合中的所有元素。
如果用for循环就有些许麻烦,针对这种需求,从1.2版本开始,JDK给我们提供了一个一个专门的接口Iterator(java.util.Iterator)。
通过API搜索,下图:
在这里插入图片描述
小拓展:

在JDK1.0的时候的迭代,用的是Enumeration ,JDK1.2开始、Iterator代替了Enumeration ,至于为什么代替,可以去看一下API找一下Enumeration对比一下就知道了。有兴趣可以去了解一下。这里只是标明就不多说了,对比一下就知道了。

如何迭代(遍历)元素?

知道了什么是迭代,什么是迭代器之后,问题就来了:如何用迭代器如何遍历集合。
在迭代器中有这样的一个方法:public interface Iterator 上面图有标出

迭代器方法
在这里插入图片描述
不用全部,用给出的其中两个方法即可实现遍历:

	boolean hasNext​() 如果迭代具有更多元素,则返回 true 。  
	E next​() 返回迭代中的下一个元素。  

示例代码:
在这里插入图片描述
从上图可以明显看到运行的每一步。通过while循环,没循环一次获取一个 值,知道判断条件为false。

迭代器的实现原理:
在这里插入图片描述
每取出一位元素,下标(指针)往下移动一位。没错,就是这么简单。

JDK5特性增强for循环(for each):
关于增强for循环,是JDK5的特性,更加简化和方便。专门用来遍历数组和集合,其底层原理就是一个迭代器。它只是在迭代器的基础上简化了书写。所以同Iterator一样所有的单列集合都可以用增强for来遍历。

	for(集合或数组的数据类型 名称:要遍历的数组或集合){
		System.out.prinln(名称)
}
	如:
		List<String> in = new ArrayList<>();
		for(String in: in){
		System.out.prinln(名称)
}
  • 问题:为什么迭代器和增强for在遍历的时候不能执行增删改查?

    因为在通过迭代器/增强for来遍历集合元素的同时,增加或者删除集合中的元素,
    【有可能】会导致某个元素被重复遍历或遍历不到。
    为什么会这样,因为数组在增删改查的时候,在删除时,数组元素往前移,就会可能重新遍历到了。

  • 问题:为什么所有单列集合都可以使用增强for?
    因为所有单列集合的父亲(Collection)都继承了Iterator迭代器接口。

    寄语:
    知识的海洋无比巨大!懂的越多,不懂的越多。
    我是山大,下期见!

本章难免会有错
误和不足之处,作者原得到广大读者的指正。

### Java 迭代器的使用方法及其常见问题解决 #### 1. 基本概念 Java 中的 `Iterator` 接口用于遍历集合对象中的元素。它提供了三个主要的方法: - `boolean hasNext()`:判断是否存在下一个可访问的元素。 - `E next()`:返回当前迭代位置的下一个元素,并将内部指针移动到下一个位置。 - `void remove()`:删除最近由 `next()` 返回的那个元素[^1]。 这些基本操作使得开发者能够在不暴露底层结构的情况下安全地访问和修改集合内容。 #### 2. 安全地从集合中移除元素 当尝试在一个循环过程中直接对原始集合进行增删改查时,容易引发 `ConcurrentModificationException` 异常。这是因为大多数集合类默认不允许在其被迭代期间发生结构性变化(除了通过其专属迭代器完成的操作之外)。为了规避此风险,推荐采用如下做法之一: ##### 使用迭代器自带的 `remove` 方法 这是最常用也是唯一合法的方式去改变正在被遍历的数据集而不触发异常。例如给定一段代码片段用来清除符合条件的所有整数值: ```java ArrayList<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4)); Iterator<Integer> iter = numbers.iterator(); while (iter.hasNext()) { Integer number = iter.next(); if (number.equals(4)) { iter.remove(); // Safe removal via iterator's method. } } System.out.println(numbers); // Output will be [1, 2, 3] ``` 这里展示了如何借助于 `Iterator` 实现无错误地剔除指定项的功能^。 #### 3. 处理中途退出迭代的情形 有时候可能因为逻辑控制而提前终止了完整的扫描过程。在这种场景下继续利用同一个实例重新拾取剩下的部分变得尤为重要。比如下面的例子说明即使中途打断正常流程依旧能够获取后续待处理单元的信息[^2]: ```java ArrayList<Integer> digits = new ArrayList<>(); for(int i=0;i<10;i++)digits.add(i); System.out.println("First pass:"); Iterator<Integer> digitIter=digits.iterator(); while(digitIter.hasNext()){ int currentDigit=digitIter.next(); System.out.print(currentDigit+" "); if(currentDigit==5){ break;// Stop iteration prematurely at value '5'. } } System.out.println("\nLeftover items:"); digitIter.forEachRemaining(System.out::print);// Print all remaining elements directly without restarting loop. /* Expected output: * First pass: * 0 1 2 3 4 5 * Leftover items: * 6789 */ ``` 上述例子清晰表明即便先前已经停止了一轮探索行动但仍可通过调用扩展函数迅速展现余留下来的成员列表[^2]. #### 4. 自定义迭代行为 对于一些复杂业务或者特殊需求而言,现有的通用型接口或许无法完全匹配实际状况下的期望效果。这时就可以考虑构建个性化的子类实现方案。举个简单的案例就是重写抽象基类里的几个核心虚函式从而达成预期目的[^4]: ```java class CustomStringIterator implements Iterator<String>{ private final String[] data={"Hello","World"}; private int index=-1; @Override public boolean hasNext(){ return ++index<data.length; } @Override public String next(){ return data[index]; } @Override public void remove(){} }; public class Main{ public static void main(String[]args)throws Exception{ CustomStringIterator customStrIt=new CustomStringIterator(); while(customStrIt.hasNext()) System.out.println(customStrIt.next()); /* Prints out each word separately line by line */ } }; ``` 这段示范程序简单明了地阐述了一个自制字符串数组迭代工具的设计思路以及具体实践步骤. --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值