博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA学习笔记--迭代器
阅读量:5949 次
发布时间:2019-06-19

本文共 5503 字,大约阅读时间需要 18 分钟。

  迭代器(Iterator)是一种设计模式。它是一个对象,它的工作是遍历并选择序列中的对象,而客户端程序员不必知道或关心该序列底层的结构。创建迭代器的代价小,因而迭代器通常被称为轻量级对象。

一、Iterable

  接口Iterable<T>,是Collection<E>等接口的超级接口。实现这个接口允许对象成为 foreach 语句的目标。

import java.util.iterator;public interface Iterable
{ Iterator
iterator(); // 返回一个在一组T类型的元素上进行迭代的迭代器 }

 

二、Iterator

  接口Iterator<E>,是对Collection进行迭代的迭代器。

  方法:Iterator<E> iterator();         // 返回在此collection元素上进行迭代的迭代器,元素返回的顺序没有保证

  JAVA的Iterator只能单向移动。使用方法iterator()要求容器返回一个在该collection上进行迭代的迭代器,Iterator将准备好返回序列中的第一个元素。

package com.tongye.iterator;import java.util.*;public class IteratorExample {    public static void main(String[] args){        List
list = new ArrayList
(); // 创建一个接收String类型元素的列表 list.add("my"); // 向list中添加元素 list.add("name"); list.add("is"); list.add("tongye"); System.out.println(list); // 打印列表 Iterator iter = list.iterator(); // 调用iterator()方法返回一个在list上进行迭代的迭代器 while(iter.hasNext()){ // 用hasNext()方法判断列表中是否还有元素 System.out.println(iter.next()); // 用next()方法返回迭代器迭代的下一个元素 iter.remove(); // 用remove()方法删除迭代器返回的最新的一个元素 } System.out.println(list); // 打印列表 }}/* output:[my, name, is, tongye]mynameistongye[]*/

  可以看到,迭代器可以遍历并选择序列中的对象,这看起来和foreach语句很像,而所有的collection都可以用foreach来遍历。当我们只是需要向前遍历collection而不需要修改collection本身时,foreach语法会显得比较实用,但如果我们需要在遍历期间修改collection,像是删除操作,则不能用foreach语法,会抛出异常,因为在使用for循环的期间调用remove()的话会改变 list.size(),从而导致了错误。这时,使用迭代器进行遍历会比较好。

  当然,迭代器的功能不仅仅只是遍历。迭代器能够将遍历序列的操作与序列底层的结构分离,达到很好的解耦效果,因此,我们也说:迭代器统一了对容器的访问方式。下面用一个例子演示一下迭代器的这个功能:

package com.tongye.iterator;import java.util.*;public class IteratorExample {    // printIterator方法用一个对一组String类型元素进行迭代的迭代器作为形参,方法体对迭代器进行遍历,    // 这是所有对String类型元素进行迭代的迭代器都可以使用的功能,而且代码是完全相同的    public static void printIterator(Iterator
iter){ while(iter.hasNext()){ // 判断迭代器是否还有元素 System.out.print(iter.next() + " "); // 打印迭代器迭代的下一个元素 } System.out.println(); } public static void main(String[] args){ List
list = new ArrayList
(); // 创建一个接收String类型元素的列表 list.add("my"); // 向list中添加元素 list.add("name"); list.add("is"); list.add("tongye"); printIterator(list.iterator()); // list.iterator()返回一个对list进行迭代的迭代器 Set
set = new HashSet
(); // 创建一个接收String类型元素的set set.add("my"); // 向set中添加元素 set.add("name"); set.add("is"); set.add("tongye"); printIterator(set.iterator()); Queue
queue = new LinkedList
(); // 创建一个接收String类型元素的队列 queue.add("my"); // 向queue中添加元素 queue.add("name"); queue.add("is"); queue.add("tongye"); printIterator(queue.iterator()); }}/* output:my name is tongye tongye name is my my name is tongye */

  可以看到,迭代器只负责遍历工作,而不关系序列是什么类型的,这样带来的好处是程序条理更为清晰,代码更为简洁。

 

三、ListIterator

  ListIterator, 系列表迭代器,是Iterator的子类型,只能用于访问List类,但是功能更为强大。允许程序按任一方向遍历列表,迭代期间修改列表,并获得迭代器在列表中的当前位置。ListIterator没有当前元素,它的光标位置始终位于调用previous()所返回的元素和调用next()所返回的元素之间。

1)Iterator只能单向移动,但是ListIterator可以双向移动;

2)可以产生相对于迭代器在列表中指向的当前位置的前一个和后一个元素的索引;

3)可以使用set()方法替换掉它访问过的最后一个元素。

下面的例子简单介绍了一下ListIterator的使用:

package com.tongye.iterator;import java.util.*;public class IteratorExample {        public static void main(String[] args){        Random rand = new Random(47);                List
list = new ArrayList
(); // 创建一个接收String类型元素的列表 list.add("my"); // 向list中添加元素 list.add("name"); list.add("is"); list.add("tongye"); ListIterator
iter = list.listIterator(); // 创建一个ListIterator iter.add("hello");  // 在迭代期间调用add()方法插入元素 while(iter.hasNext()){ // hasNext()方法,正向遍历,如果list中还有元素,则返回true System.out.print(iter.nextIndex() + ":");   // nextIndex()方法,返回对next的后续调用所返回元素的索引 System.out.print(iter.next() + " "); } System.out.println(); while(iter.hasPrevious()){ // hasPrevious()方法,逆向遍历,如果list中还有元素,则返回true System.out.print(iter.previousIndex() + ":"); // previousIndex()方法,返回对previous的后续调用所返回元素的索引 System.out.print(iter.previous() + " "); } System.out.println(); while(iter.hasNext()){ iter.next(); iter.set(list.get(rand.nextInt(4))); // set()方法,用指定元素替换next或previous返回的最后一个元素 } System.out.println(list); }}/* output:1:my 2:name 3:is 4:tongye 4:tongye 3:is 2:name 1:my 0:hello [name, my, name, name, name]* */

  关于add()方法,用下面这张图来说明一下:ListIterator.add()方法可以在迭代期间向列表中添加元素,元素添加的位置是当前光标所在位置之前(next()所返回的下一个元素之前(如果有),previous()所返回的下一个元素之后(如果有))。因此,用add()添加一个元素,并不会影响插入的这一次遍历中对next()的后续调用,因此在上面的程序,第一次调用next()方法并没有输出添加的元素 hello;但是会对previous的后续调用有影响,添加的这个元素将是previous后续调用的第一个元素。

  关于 ListIterator.set()方法,可以用指定元素替换 next 或 previous 返回的最后一个元素(可选操作),只有在最后一次调用 next 或 previous 后既没有调用ListIterator.add() 也没有调用 ListIterator.remove()是才可以进行该调用。

 

转载于:https://www.cnblogs.com/tongye/p/6731111.html

你可能感兴趣的文章
2019 年 5 月 Android 开发热门开源项目
查看>>
线程关键字、锁、同步集合笔记
查看>>
前端规范之HTML 规范
查看>>
ios安装cocoaPods
查看>>
小程序营销组件
查看>>
大数据学习笔记1
查看>>
【NOIP】提高组2016 愤怒的小鸟
查看>>
React 30 秒速学:制作星级评分组件
查看>>
Nginx配置详解
查看>>
leetcode 326. Power of Three
查看>>
陈云峰:区块链技术在金融领域的应用与思考
查看>>
time.js 时间函数库
查看>>
部署模式 - 每个主机多个服务实例
查看>>
COJS:1829. [Tyvj 1728]普通平衡树
查看>>
SpringBoot 教程之 profile
查看>>
面试题编程题08-python 垃圾回收机制
查看>>
排序--冒泡
查看>>
java中int->String 3种方式效率分析
查看>>
AndroidStudio、gradle、buildToolsVersion关系
查看>>
Eclipse中java文件和jsp字体大小设置
查看>>