1.10 Iterator(迭代器)遍历集合元素

Iterator(迭代器)遍历Collection集合元素

Iterator(迭代器)是一个接口,它的作用就是遍历容器的所有元素,也是 Java 集合框架的成员,但它与 Collection 和 Map 系列的集合不一样,Collection 和 Map 系列集合主要用于盛装其他对象,而 Iterator 则主要用于遍历(即迭代访问)Collection 集合中的元素。

Iterator 接口隐藏了各种 Collection 实现类的底层细节,向应用程序提供了遍历 Collection 集合元素的统一编程接口。Iterator 接口里定义了如下 4 个方法。

  • boolean hasNext():如果被迭代的集合元素还没有被遍历完,则返回 true。
  • Object next():返回集合里的下一个元素。
  • void remove():删除集合里上一次 next 方法返回的元素。
  • void forEachRemaining(Consumer action):这是 Java 8 为 Iterator
    新增的默认方法,该方法可使用 Lambda 表达式来遍历集合元素。

下面程序示范了通过 Iterator 接口来遍历集合元素。

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

public class Test {
	public static void main(String[] args) {
	 //创建一个集合
		Collection objs=new HashSet();
		  objs.add("111");
	      objs.add("222");
	      objs.add("333");
	      objs.add("444");
	      objs.add("555");
	        
	     //调用forEach()方法遍历集合,获取集合对应的迭代器
	      Iterator it=objs.iterator();
	      while(it.hasNext()){
	    	// it.next()方法返回的数据类型是Object类型,因此需要强制类型转换
	            String obj = (String) it.next();
	            System.out.print(obj+" ");
	            if (obj.equals("111")) {
	                // 从集合中删除上一次next()方法返回的元素
	                it.remove();
	            }
	            // 对变量赋值,不会改变集合元素本身
	            obj = "aaa";
	        }
	        System.out.print("\n"+objs);
	    }
	}

运行结果:

111 222 333 444 555 
[222, 333, 444, 555]

从上面代码中可以看出,Iterator 仅用于遍历集合,如果需要创建 Iterator 对象,则必须有一个被迭代的集合。没有集合的 Iterator 没有存在的价值。

注意:Iterator 必须依附于 Collection 对象,若有一个 Iterator 对象,则必然有一个与之关联的 Collection 对象。Iterator 提供了两个方法来迭代访问 Collection 集合里的元素,并可通过 remove() 方法来删除集合中上一次 next() 方法返回的集合元素。

上面程序中 obj = "aaa";代码对迭代变量 obj 进行赋值,但当再次输岀 objs 集合时,会看到集合里的元素没有任何改变。所以当使用 Iterator 对集合元素进行迭代时,Iterator 并不是把集合元素本身传给了迭代变量,而是把集合元素的值传给了迭代变量,所以修改迭代变量的值对集合元素本身没有任何影响。

当使用 Iterator 迭代访问 Collection 集合元素时,Collection 集合里的元素不能被改变,只有通过 Iterator 的 remove() 方法删除上一次 next() 方法返回的集合元素才可以,否则将会引发“java.util.ConcurrentModificationException”异常。下面程序示范了这一点。

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

public class Test {
	public static void main(String[] args) {
	 //创建一个集合
		Collection objs=new HashSet();
		  objs.add("111");
	      objs.add("222");
	      objs.add("333");
	      objs.add("444");
	      objs.add("555");
	        
	     //调用forEach()方法遍历集合,获取集合对应的迭代器
	      Iterator it=objs.iterator();
	      while(it.hasNext()){
	    	// it.next()方法返回的数据类型是Object类型,因此需要强制类型转换
	            String obj = (String) it.next();
	            System.out.print(obj+" ");
	            if (obj.equals("111")) {
	                // 使用Iterator迭代过程中,不可修改集合元素,下面代码引发异常
	                objs.remove(obj);
	            }
	      }
	    }
	}

运行结果:
在这里插入图片描述
上面程序中 objs.remove(obj);代码位于 Iterator 迭代块内,也就是在 Iterator 迭代 Collection 集合过程中修改了 Collection 集合,所以程序将在运行时引发异常。

Iterator 迭代器采用的是快速失败(fail-fast)机制,一旦在迭代过程中检测到该集合已经被修改(通常是程序中的其他线程修改),程序立即引发 ConcurrentModificationException 异常,而不是显示修改后的结果,这样可以避免共享资源而引发的潜在问题

快速失败(fail-fast)机制,是 Java Collection 集合中的一种错误检测机制。

注意:上面程序如果改为删除“111”字符串,则不会引发异常。这样可能有些读者会“心存侥幸”地想,在迭代时好像也可以删除集合元素啊。实际上这是一种危险的行为。对于 HashSet 以及后面的 ArrayList 等,迭代时删除元素都会导致异常。只有在删除集合中的某个特定元素时才不会抛出异常,这是由集合类的实现代码决定的,程序员不应该这么做。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值