在Java中,Iterator的作用就是为了方便处理集合中的元素。例如获取和删除集合中的元素。

在JDK8,Iterator接口提供了如下方法:

迭代器Iterator最基本的两个方法是next()和hasNext()。其中Java迭代器多了一个remove()方法。在JDK8中又新增了forEachRemaining()方法。

接下来,以ArrayList为例,看下迭代器在Java中的实现。

在ArrayList中,以内部类的方式实现,每次调用iterator()方法,都会new Itr()。

先看一下ArrayList迭代器的实现类:

定义的参数如下:

 int cursor;       // 下标,默认值0;
int lastRet = -1; //最后一个元素的下标,如果没有返回-1;
int expectedModCount = modCount;//结构修改(添加、删除等操作)次数,默认值0;

定义的方法如下:

hasNext()方法:

  public boolean hasNext() {
return cursor != size;
}

当集合中不存在下一个元素,即已经遍历至集合末尾时,该方法返回false。hasNext 方法主要用于循环终止条件。

next()方法:

 public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}

在执行next()方法时,会先执行checkForComodification()方法,做一个判断(检查所迭代的列表对象是否被修改过):

 final void checkForComodification() {
if (modCount != expectedModCount) throw new ConcurrentModificationException();
}

在对集合进行迭代过程中,不允许出现迭代器以外的对元素的操作,因为这样会产生安全隐患,java会抛出异常并发修改异常(ConcurrentModificationException),普通迭代器只支持在迭代过程中的删除动作。

如果在遍历ArrayList时,想添加元素和修改元素,可以调用List集合的特有迭代器ListIterator。

remove()方法:

 public void remove() {
if (lastRet < 0) throw new IllegalStateException();
checkForComodification(); try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}

Java普通迭代器中唯一支持修改结构的操作。在执行完删除操作后,会更新expectedModCount字段的值。

forEachRemaining()方法:

 public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}

forEachRemaining()是JDK8中新增的方法。forEachRemaining()使用迭代器Iterator的所有元素,并且第二次调用它将不会做任何事情,因为不再有下一个元素。

一个使用场景:获得对应集合的迭代器Iterator,然后您可以开始迭代,next()直到达到某个条件,然后使用forEachRemaining()操作该Iterator上的其余部分。

接下来,看一下刚才提到的ListIterator。

在普通的Iterator中,只能对元素进行获取(next())和删除(remove())的操作。而ListIterator提供了更多的方法:

add(E e): 将指定的元素插入列表,插入位置为迭代器当前位置之前
hasNext():以正向遍历列表时,如果列表迭代器后面还有元素,则返回 true,否则返回false
hasPrevious():如果以逆向遍历列表,列表迭代器前面还有元素,则返回 true,否则返回false
next():返回列表中ListIterator指向位置后面的元素
nextIndex():返回列表中ListIterator所需位置后面元素的索引
previous():返回列表中ListIterator指向位置前面的元素
previousIndex():返回列表中ListIterator所需位置前面元素的索引

在使用特有的迭代器时,我们就能做更多的操作了。

Iterator-Java的更多相关文章

  1. 迭代器模式-Iterator(Java实现)

    迭代器模式-Iterator 用于访问一个集合中的各个元素, 而又不会暴露集合的内部的细节. 本文展示的例子就是, 在猫群组里, 用迭代器遍历每一只猫. 本文章的例子的继承关系图如下: 其中: Cat ...

  2. Java 中Iterator 、Vector、ArrayList、List 使用深入剖析

    标签:Iterator Java List ArrayList Vector 线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构.这些 ...

  3. Java 集合系列18之 Iterator和Enumeration比较

    概要 这一章,我们对Iterator和Enumeration进行比较学习.内容包括:第1部分 Iterator和Enumeration区别第2部分 Iterator和Enumeration实例 转载请 ...

  4. Java集合--Iterator和Enumeration比较

    转载请注明出处:http://www.cnblogs.com/skywang12345/admin/EditPosts.aspx?postid=3311275 第1部分 Iterator和Enumer ...

  5. Scala集合和Java集合对应转换关系

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 用Scala编码的时候,经常会遇到scala集合和Java集合互相转换的case,特意mark一 ...

  6. Java设计模式(二)——迭代模式

    迭代模式的基本定义:对于一组对象集合(数组.堆栈.列表或散列),用户无需关心它的底层实现而能够通过调用统一接口遍历当中的所有元素.由于jdk已经对常见的迭代模式实现了封装,本文直接提供Collecti ...

  7. Java基础常见英语词汇

    Java基础常见英语词汇(共70个) ['ɔbdʒekt] ['ɔ:rientid]导向的                             ['prəʊɡræmɪŋ]编程 OO: object ...

  8. Iterator<转>

    Iterator就是迭代器的意思. Iterator是一个接口,利用迭代器主要是获取元素,很少删除元素.有三个方法:    1)hasNext():判断是否有更多的元素,如果有返回true.    2 ...

  9. 迭代器模式(Iterator Pattern)

    迭代器模式定义:Iterator Pattern提供一种方法顺序访问一个聚合元素中的各个元素,而又不暴漏内部方法 酒吧提供beer和wine: public class Bar { private L ...

  10. 《Velocity java开发指南》中文版(上)转载

    文章引自:http://sakyone.iteye.com/blog/524289 1.开始入门 Velocity是一基于java语言的模板引擎,使用这个简单.功能强大的开发工具,可以很容易的将数据对 ...

随机推荐

  1. C++程序设计1(侯捷video 1-6)

    一.头文件的防御式声明(video2) #ifndef __COMPLEX__ #define __COMPLEX__ //内容 #endif 二.初步感受模板(video2) 定义的时候: //复数 ...

  2. HBase 学习之路(六)——HBase Java API 的基本使用

    一.简述 截至到目前(2019.04),HBase 有两个主要的版本,分别是1.x 和 2.x ,两个版本的Java API有所不同,1.x 中某些方法在2.x中被标识为@deprecated过时.所 ...

  3. java基础知识总结(二)

    Java中的代码块 java中的代码块是用{}括起来的代码,进行一些功能的限定 静态代码块:在类第一次被初始化的是后执行,负责一些类的初始化操作,仅仅只执行一次 构造代码块:顾名思义,辅助构造器进行初 ...

  4. 【React】存储全局数据

    参考链接:https://segmentfault.com/a/1190000012057010?utm_source=tag-newest webstorage webstorage是本地存储,存储 ...

  5. IT需求过程管理

    IT部门就是为其他业务.内勤部门提供信息化手段的,所以在实施信息化系统的时候首先要做的就是需求调研,但是针对于绝大多数业务部门的人员而言,信息系统是很不熟悉的,我们会经常听到这样的回复“这个应该很快就 ...

  6. java虚拟机-GC-新生代的GC、老年代的GC

    名词解释: GC:垃圾收集器 Minor GC:新生代GC,指发生在新生代的垃圾收集动作,所有的Minor GC都会触发全世界的暂停(stop-the-world),停止应用程序的线程,不过这个过程非 ...

  7. 小容量单片机生成pdf文件

    工作上要求使用小容量单片机生成直接生成pdf文件.经过一段时间的摸索,其中参考了libharu,库太大,不适合在单片机上使用页参考了与非网上一位前辈的库,占用的RAM太大,不适合小容量单片机,主要资料 ...

  8. 关于char[]转换成LPCWSTR的有关问题[转]

    一.问题的原因:VS2010默认采用宽字符UNICODE编码方式,定义了Unicode,因此相关的字符串必须为unicode字符串,而非ascii字符串. LPCWSTR中的W是宽字符的意思,是UNI ...

  9. mysql重复数据下,删除一条重复数据

    delete from information where id in (select id from (select max(id) as id,count(*) as ccc from infor ...

  10. centos7安装hadoop完全分布式集群

    groupadd test             //新建test工作组 useradd -g test phpq        //新建phpq用户并增加到test工作组 userdel 选项 用 ...