简介

迭代器是遍历容器的一种常用方法,它屏蔽了容器的实现细节,无需暴露数据结构内部,就可以对容器进行遍历,迭代器本身也是一种设计模式,迭代是一种特殊的遍历方式

Iterator

在java中,迭代器接口Iterator定义了三种方法

public interface Iterator<E> {

  // 是否还有元素可以迭代,如果有 返回true 没有返回false
boolean hasNext(); // 返回迭代的下一个元素
E next(); // 从迭代器指向的 collection 中移除迭代器返回的最后一个元素
void remove();
}

remove方法是移除迭代器返回的最后一个元素,因此如果没有调用过next方法,直接调用remove方法是错误的做法,并且每执行一次next方法,只能调用一次remove方法

Iterable

Iterable只有一个iterator方法,该方法会返回一个迭代器,一般情况下使用迭代器的类都会实现Iterable接口而非直接实现Iterator接口

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

foreach 就是对迭代器的另外一种使用方式,只要是实现Iterable接口的类,就可以用foreach对自身进行遍历

map 迭代

map接口并未继承Iterable接口,因此本身并不能直接使用迭代器,不过可以转化为collection然后进行迭代,例如:

Map<String, String> map = new HashMap<>();
map.put("韦德", "35");
Iterator<Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, String> entry = iterator.next();
System.out.println(entry.getKey() + ":" + entry.getValue());
}

map的遍历方式可参考 java中遍历Map的几种方法

collection 迭代

collection接口继承了Iterable接口,因此只要是collection实例,都可以使用迭代器进行遍历

Collection<String> collection = Arrays.asList("java", "c", "js");
Iterator<String> iterator = collection.iterator();
while (iterator.hasNext()) {
String str = iterator.next();
System.out.println(str);
}

用迭代器遍历collection的优势在于遍历的过程中可以remove元素,用foreach则不行

ListIterator

ListIterator是对Iterator的扩展,针对定义了ListIterator方法的有序的容器,可以采用ListIterator进行迭代,ListIterator新增了一些方法,可以在遍历时获取数据的索引,或者逆序遍历等。

public interface ListIterator1<E> extends Iterator<E> {

  // 是否还有上一个元素 一般逆序遍历时使用
boolean hasPrevious(); // 返回列表中的上一个元素
E previous(); // 返回对 next 的后续调用所返回元素的索引。(如果列表迭代器在列表的结尾,则返回列表的大小)
int nextIndex(); // 返回对 previous 的后续调用所返回元素的索引。(如果列表迭代器在列表的开始,则返回 -1)
int previousIndex(); // 用指定元素替换 next 或 previous 返回的最后一个元素(可选操作)。只有在最后一次调用 next 或 previous
// 后既没有调用 ListIterator.remove 也没有调用 ListIterator.add 时才可以进行该调用。
void set(E e); // 将指定的元素插入列表(可选操作)。该元素直接插入到 next 返回的下一个元素的前面(如果有)
//或者 previous 返回的下一个元素之后(如果有);
void add(E e); // ... Iterator methods
}

List提供了两个重载的listIterator方法,可以通过这两个方法拿到一个ListIterator对象

public interface List1<E> extends Collection<E> {

  // 此列表元素的列表迭代器
ListIterator<E> listIterator(); // 此列表元素的列表迭代器 可以指定一个参数index
// index 从列表迭代器返回的第一个元素的索引(通过调用 next 方法)
ListIterator<E> listIterator(int index); // List other methods }

使用listIterator对List进行逆序遍历

List<String> list = Arrays.asList("java", "c", "js");
ListIterator<String> listIterator = list.listIterator(list.size());
while (listIterator.hasPrevious()) {
System.out.println("前一个元素索引为:" + listIterator.previousIndex());
System.out.println("前一个元素为:" + listIterator.previous());
}

光标(cursor)

迭代器没有当前元素的概念,但有光标(cursor)的概念,

如果不指定光标的位置,光标默认在第一个元素之前,此时如果调用next方法,光标会跳到第一个元素和第二个元素中间,并且返回第一个元素

ListIterator<String> listIterator = list.listIterator(list.size());

以上代码,指定了光标的位置,在最后一个元素的后面,此次要调用next方法会抛异常,因为没有下一个元素,如果调用nextIndex则会返回容器长度,调用previous则返回最后一个元素,同时光标向上移动一位

总结

迭代器在使用的过程中其实还有诸多限制,如果使用不当,很可能出现死循环,抛异常等问题,例如:如果在用ListIterator逆序遍历的时候新增,会造成死循环。

因此在学习迭代器的时候,不仅要掌握其使用方法,还要明白其实现原理。看源码是不错的学习办法,有兴趣的可以看看Collection的众多实现类对迭代的实现。

java迭代器浅析的更多相关文章

  1. 黑马----JAVA迭代器详解

    JAVA迭代器详解 1.Interable.Iterator和ListIterator 1)迭代器生成接口Interable,用于生成一个具体迭代器 public interface Iterable ...

  2. 设计模式 - 迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释

    迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考迭代器模式(ite ...

  3. Java迭代器[转]

    迭代器是一种模式,它可以使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的.只要拿到这个对象,使用迭代器就可以遍历这个对象的内部. 1.Iterator ...

  4. Java 迭代器综述

    一.摘要 迭代器模式是与集合共生共死的.一般来说.我们仅仅要实现一个容器,就须要同一时候提供这个容器的迭代器.使用迭代器的优点是:封装容器的内部实现细节,对于不同的集合,能够提供统一的遍历方式,简化c ...

  5. Java迭代器的一般用法

    迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为“轻量级”对象,因为创建它的代价小. Java中的I ...

  6. 170118、快速失败Vs安全失败(Java迭代器附示例)

    简介: 当错误发生时,如果系统立即关闭,即是快速失败,系统不会继续运行.运行中发生错误,它会立即停止操作,错误也会立即暴露.而安全失败系统在错误发生时不会停止运行.它们隐蔽错误,继续运行,而不会暴露错 ...

  7. 【Java学习】Java迭代器

    迭代器是一种模式,它可以使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的.只要拿到这个对象,使用迭代器就可以遍历这个对象的内部. 1.Iterator ...

  8. Java迭代器的用法【转】

    迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为“轻量级”对象,因为创建它的代价小. Java中的I ...

  9. [转载]Java迭代器(iterator详解以及和for循环的区别)

    Java迭代器(iterator详解以及和for循环的区别) 觉得有用的话,欢迎一起讨论相互学习~[Follow] 转载自 https://blog.csdn.net/Jae_Wang/article ...

随机推荐

  1. EntityFramework Core迁移时出现数据库已存在对象问题解决方案

    前言 刚开始接触EF Core时本着探索的精神去搞,搞着搞着发现出问题了,后来就一直没解决,觉得很是不爽,借着周末好好看看这块内容. EntityFramework Core迁移出现对象在数据库中已存 ...

  2. Kubernets 资源类型简介

    # Node 代表 Kubernets 集群运行的宿主物理机或者虚拟服务器, 为容器提供必要的计算资源: 内存 与 CPU 等. # Pod 最底层的抽象. 一个 Pod 中可以包含一个或者多个运行的 ...

  3. windows下pycharm远程调试pyspark

    参考http://www.mamicode.com/info-detail-1523356.html1.远端执行:vi /etc/profile添加一行:PYTHONPATH=$SPARK_HOME/ ...

  4. thinkphp导出csv格式的表格

    <?php /** * Created by PhpStorm. * User: hanks * Date: 2016/4/20 * Time: 13:51 */ namespace Home\ ...

  5. php根据经纬度获取城市名

    /*php根据经纬度获取城市名*/ function get_my_addr_infos(){ $ch = curl_init(); $timeout = 5; $lat = $list['info' ...

  6. IOS 状态栏(UIStatusBar)

    ios上状态栏指的屏幕顶端的20像素高的部分 状态栏分前景和背景两部分 前景部分:就是指的显示电池.时间等部分: 背景部分:就是显示白色或者图片的背景部分: 如下图:前景部分为黑色字体,背景部分为白色 ...

  7. accp8.0转换教材第8章JavaScript对象及初识面向对象理解与练习

    JavaScript数据类型,对象,构造函数,原型对象,初识原型链,对象继承 一.单词部分 ①object父类②constructor构造函数③instance实例④call调用 ⑤apply应用⑥c ...

  8. 【ESP8266】发送HTTP请求

    一.ESP8266简介 ESP8266 是深圳安信可科技有限公司开发的基于乐鑫ESP8266的超低功耗的UART-WIFI模块的模组,可以方便进行二次元开发,接入云端服务,实现手机3/4G全球随时随地 ...

  9. java基础系列--Date类

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/7126930.html 1.Date类概述 Date类是从JDK1.1就开始存在的老类,其提 ...

  10. 基于angular4.0分页组件

    分页组件一般只某个页面的一小部分,所以我们它是子组件 当然如果你承认这话的,可以往下看,因为我把他当作子组建来写了 分页组件的模版 import { Component } from '@angula ...