在前面大致讲解了Collection这个根接口的知识,让我们知道Collection接口是List、Set和Queue接口的父接口,该接

口里定义的方法既可用于操作Set集合,也可用于操作List和Queue集合。关于Collection下的子接口和实现类在后面

会讲解到,今天我们来看下Iterator接口,如下程序:

public interface Collection<E> extends Iterable<E>

Collection这个根接口继承了Iterable接口,我们来看下Iterable接口中定义的方法:

Iterator<T> iterator();

Iterator接口也是Java集合框架的成员,只是它与Collection系列、Map系列的集合不一样,Collection系列集合、Map

系列集合主要用于盛装其他对象,而Iterator主要用于遍历Collection集合中的元素,Iterator对象也被称为迭代

器。Iterator接口隐藏了各种Collection实现类的底层细节,向应用程序提供了遍历Collection集合元素的统一编程接

口。

关于Iterator接口定义的方法:

boolean hasNext();

hasNext的用法:如果被迭代的集合元素还没有遍历完,返回true。

E next();

next的用法:返回集合里的下一个元素。

default void remove() {throw new UnsupportedOperationException("remove");}

remove的用法:删除集合里上一次next方法返回的元素。如果迭代器不支持remove操作的话,就会抛出上面的

UnsupportedOperationException异常。

Iterator的用法如下程序:

public class IteratorTest {public static void main(String[] args) {Collection collection=new HashSet();collection.add("Bill");collection.add(2);collection.add(true); Iterator iterator=collection.iterator();       while(iterator.hasNext()){System.out.println(iterator.next());}}}

关于HashSet在后续讲解时会提到,有一点需记住HashSet是通过Hash算法来存储集合中的元素的。通过Collection接

口中add方法添

加元素,并通过被迭代的集合来获取Iterator对象,最后分别输出集合的元素。

以下是我们常发生的错误:

public class IteratorTest {public static void main(String[] args) {Collection collection=new HashSet();collection.add("Bill");collection.add("Jack");collection.add("Sun");   Iterator iterator=collection.iterator();       while(iterator.hasNext()){String name=(String)iterator.next();System.out.println(name);if(name.equals("Jack")){collection.remove(name);} }}}

输出:

Bill
Jack
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$KeyIterator.next(HashMap.java:1453)
at code2.IteratorTest.main(IteratorTest.java:27)

以上程序在进行迭代时,删除第二个元素“Jack”时引发异常,我们来看看ConcurrentModificationException引发异常

的真正原因:

当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。

例如,某个线程在 Collection 上进行迭代时,通常不允许另一个线性修改该 Collection。通常在这些情况下,迭代的

结果是不确定的。如果检测到这种行为,一些迭代器实现(包括 JRE 提供的所有通用 collection 实现)可能选择抛

出此异常。执行该操作的迭代器称为快速失败 迭代器,因为迭代器很快就完全失败,而不会冒着在将来某个时间任

意发生不确定行为的风险。

注意,此异常不会始终指出对象已经由不同 线程并发修改。如果单线程发出违反对象协定的方法调用序列,则该对

象可能抛出此异常。例如,如果线程使用快速失败迭代器在 collection 上迭代时直接修改该 collection,则迭代器将

抛出此异常。

注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保

证。快速失败操作会尽最大努力抛出 ConcurrentModificationException。因此,为提高此类操作的正确性而编写一个

依赖于此异常的程序是错误的做法,正确做法是:ConcurrentModificationException 应该仅用于检测 bug。

OK,如果我们改成删除第一个元素“Bill”呢?

public class IteratorTest {public static void main(String[] args) {Collection collection=new HashSet();collection.add("Bill");collection.add("Jack");collection.add("Sun");   Iterator iterator=collection.iterator();       while(iterator.hasNext()){String name=(String)iterator.next();System.out.println(name);if(name.equals("Bill")){collection.remove(name);} }}}

输出:

Bill
Exception in thread "main" java.util.ConcurrentModificationExceptionat java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)at java.util.HashMap$KeyIterator.next(HashMap.java:1453)at code2.IteratorTest.main(IteratorTest.java:27)

好吧,又引发异常了,那改成删除最后一个元素呢?

public class IteratorTest {public static void main(String[] args) {Collection collection=new HashSet();collection.add("Bill");collection.add("Jack");collection.add("Sun");   Iterator iterator=collection.iterator();       while(iterator.hasNext()){String name=(String)iterator.next();System.out.println(name);if(name.equals("Sun")){collection.remove(name);}  }}}

输出:

Bill
Jack
Sun

以上程序终于删除了最后一个元素。现在我们终于知道,当我们使用Iterator迭代访问Collection集合元素时,

Collection集合里的元素不能被改变,只有通过Iterator的remove方法删除上一次next方法返回的集合元素才可以,否

则将会引发ConcurrentModificationException异常,以上程序,是在遍历最后一个元素后删除最后的元素,其实在使

用next方法遍历到最后的元素后,如果再调用hashNext就会返回false,也就是说遍历到最后一个元素后,迭代就已经

完毕了,也就不存在当使用Iterator迭代访问Collection集合元素时,对集合元素进行改变了。

转载请注明出处:http://blog.csdn.net/hai_qing_xu_kong/article/details/44001581  情绪控_

Java学习笔记24相关推荐

  1. Java学习笔记24(Map集合)

    Map接口: Map接口与Collection接口无继承关系. 区别:Collection中的元素是孤立的,一个一个存进去的. Map作为一个映射集合,每一个元素包含Key-value对(键-值对). ...

  2. JAVA学习笔记24——SpringBoot

    SpringBoot 微服务架构 把每个功能元素独立出来,把独立出来的功能元素动态组合,需要的功能元素才去拿来组合,需要多一些时可以聚合多个功能元素,所以微服务架构是对功能元素进行复制,而没有对整个应 ...

  3. Java学习笔记(十)--控制台输入输出

    输入输出 一.控制台输入 在程序运行中要获取用户的输入数据来控制程序,我们要使用到 java.util 包中的 Scanner 类.当然 Java 中还可以使用其他的输入方式,但这里主要讲解 Scan ...

  4. 【Java学习笔记之二十六】深入理解Java匿名内部类

    在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意 ...

  5. Java学习笔记22:并发(2)

    Java学习笔记22:并发(2) 图源:PHP中文网 终止任务 终止线程有一种非常简单的方式:设置一个多线程共享的标记位,子线程用轮询的方式检查这个标记位,如果该标记位显示取消状态,就让子线程退出执行 ...

  6. Java学习笔记——流程控制

    Java学习笔记--流程控制 Day05 一.用户交互Scanner 1.Scanner对象 我们通过Java工具包java.util.Scanner中的Scanner类来获取用户的输入 基本语法:S ...

  7. Java学习笔记Day02

    Java学习笔记Day02 一.细化Hello程序 1.详解代码 //公有的类,叫做Hello public class Hello{//主方法public static void main(Stri ...

  8. Java学习笔记 2021-7-1 2021-7-8

    Java学习笔记 Stream流 1 Stream流的体验 stream流的生成操作 stream中间流操作 filter limit和skip concat和distinct sorted map和 ...

  9. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

最新文章

  1. ionic 笔记-wzq
  2. 【转】Linux下Oracle sqlplus无法使用命令退格删除和历史记录的解决方法(使用rlwrap)...
  3. Ubuntu 之 atom 安装以及 常用配置
  4. 球面三角基本名称及性质、基本定理和公式、解法
  5. 今天悄悄的给你说几个HashCode的破事。
  6. nginx搭建静态服务器(127.0.0.1/localhost访问)
  7. oracle链接池满了怎么办,Oracle连接数满了
  8. python顺序结构逆序三位数_Python练习题3.20逆序的三位数
  9. 做程序员的老婆应该注意的一些事情
  10. 【转】oracle order by 处理NULL 值
  11. 毕设题目:Matlab图像检索
  12. java怎么实现微博评论_用户操作之回复评论、查看微博评论功能实现一
  13. 【对讲机的那点事】带你玩转宝锋UV6R对讲机(四)
  14. 多元线性回归:客户价值预测
  15. formula的java用法_java-@Formula无法在休眠状态下与对象一起使用
  16. STM32cubeIDE生成HEX文件
  17. 一句话+一张图——说清楚Aprioir关联规则算法
  18. 微信小程序留言板设计
  19. javascript 异步_javascript异步操作使您的网站充满活力
  20. 一张图看懂在北京买房不同贷款方式的差别

热门文章

  1. 7 centos 设置jvmgc_centos7配置java环境变量
  2. 第2章 S交换机管理平面安全
  3. swift3 0 Alamofire下载文件
  4. idea搭建简单spring-boot项目
  5. 动态生成CheckBox(Winform程序)
  6. TP 框架没有考虑完善的功能点:1、表达式查询不支持INSTR形式的查询
  7. Linux基础(9)文本处理三剑客之grep
  8. 第十二周项目1-阅读程序(三)
  9. jbpm binding类深入解析
  10. 正则表达式和re模块知识点汇总