Java 集合:(三) Iterator迭代器接口

一、Iterable 接口

  1、Iterable 是 java.lang 包下面的一个接口,实现此接口可使对象成为“ for-each循环”语句的目标,同时里面还有获取迭代器的方法。

  

  方法说明:

Iterator<T> iterator():获取迭代器对象

default void forEach(Consumer<? super T> action) 

default Spliterator<T> spliterator()

  其中default 方法的实现如下:

二、Iterator 接口

  1、概述

    (1)Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素,它替代了 JCF 中的 Enumeration 接口。

    (2)GOF给迭代器模式的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。 迭代器模式,就是为容器而生。迭代器(Iterator)有时又称为游标(cursor),提供一种方法访问一个容器(container)对象中各个元素,而又不暴露该对象的内部细节。

    (3)Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了
Iterator接口的对象。

    (4)Iterator 仅用于遍历集合Iterator 本身并不提供承装对象的能力。如果需要创建Iterator 对象,则必须有一个被迭代的集合。

    (5)集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。

  2、Iterator 接口的方法

    

      

       方法概述:

boolean hasNext():这个方法是在遍历的时候,判断是否还有更多的元素

E next(): 返回下一个元素

default void remove():这里涉及到了jdk8的特性,在接口定义中,将方法描述为default-虚拟扩展方法,
就可以在接口中进行默认实现,从而提高接口的扩展性,避免在接口扩展的时候,破坏原有的实现。 default void forEachRemaining(Consumer<? super E> action):对剩余的每个元素执行给定的操作,这个方面一般都用不到,不做具体描述。

  

     注意

    (1)在调用it.next()方法之前必须要调用it.hasNext()进行检测。若不调用,且下一条记录无效,直接调用it.next()会抛出NoSuchElementException异常

    (2)集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前;

    (3)内部定义了remove(),可以在遍历的时候,删除集合中的元素。此方法不同于集合直接调用remove();

  3、迭代器的执行原理

    

  4、Iterator 接口的 remove() 方法

    代码示例:

1 Iterator iter = coll.iterator();//回到起点
2 while(iter.hasNext()){
3     Object obj = iter.next();
4     if(obj.equals("Tom")){
5         iter.remove();
6     }
7 }

    注意:

    (1)Iterator可以删除集合的元素, 但是是遍历过程中通过迭代器对象的remove方法, 不是集合对象的remove方法。

    (2)如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,再调用remove都会报IllegalStateException

  5、使用 foreach 循环遍历集合元素

    (1)Java 5.0 提供了 foreach 循环迭代访问 Collection和数组;

    (2)遍历操作不需获取Collection或数组的长度,无需使用索引访问元素;

    (3)遍历集合的底层调用Iterator完成操作;

    (4)foreach还可以用来遍历数组。

      

  6、集合中的迭代器

  迭代器是为容器遍历而生,用以方便的实现对容器内元素的遍历操作。类似于“公交车上的售票员”、“飞机上的空姐”,他们只为关注当前“容器”中的乘客,可以“访问”每一位乘客。例如:公交车上的售票员走到每个座位之前,看看是否有乘客,如果有检查该乘客,如果该乘客未购票,可以请他下车,也只能请刚刚检查过的乘客下车。每一类集合都有自己的迭代器,迭代器是为对应的集合服务的,因此迭代器都是作为对应集合的内部类定义的。

  示例:摘取关键代码 ArrayList 的内部迭代器 Itr。

  

三、ListIterator 接口

  ListIterator 列表的迭代器,继承自 Iterator,可以从列表的两端进行遍历(Iterator只能从前到后)。
  java.util.ListIterator 接口继承了 Iterator 接口,在 List 系列的集合中每一个实现类中,有一个内部类实现了 ListIterator 接口,用于 List 集合的迭代。
  继承结构与方法列表:
  

   它在 Iterator 基础上增加方法如下:

// 是否有前一个元素(可理解为从后往前遍历)
boolean hasPrevious();

// 获取前一个元素
E previous();

// 返回对 next() 的后续调用将返回的元素的索引
// 如果列表迭代器位于列表的末尾,则返回列表大小
int nextIndex();

// 返回对 previous() 的后续调用将返回的元素的索引
// 如果列表迭代器位于列表的开头,则返回 -1
int previousIndex();

// 用指定的元素替换 next() 或 previous() 返回的最后一个元素
void set(E e);

// 插入指定元素到列表中
void add(E e);

  5个方法。通过前3个方法可以进行向前遍历元素,后面两个 set 和 add 可以插入元素,但是 set 是将元素插入到链表的最后位置,add 是插入到当前返回的元素之前。

  注意:迭代器的游标在元素之间,如下:

/*
*                         Element(0)        Element(1)        Element(2)        ... Element(n-1)
* cursor positions:  ^                       ^                       ^                          ^                             ^
*/
 

四、Iterator 接口与 ListIterator 接口区别与联系

  1、ListIterator 继承自 Iterator;
  2、都有 remove() 方法,都可以删除对象;
  3、都有 next() 和 hasNext() 方法,都可以实现向后遍历;而 ListIterator 有 previous() 和 hasPrevious() 方法,可以向前遍历;
  4、ListIterator 有 add() 和 set() 方法,可以向 List 添加和修改元素;而 Iterator 不能。
原文地址:https://www.cnblogs.com/niujifei/p/14671730.html