• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Java > Java集合框架中迭代器Iterator解析

Java集合框架中迭代器Iterator解析

作者:Java开发-搁浅 字体:[增加 减小] 来源:互联网 时间:2017-05-28

Java开发-搁浅 通过本文主要向大家介绍了java集合框架,java集合框架详解,java集合框架图,java中的集合框架,java集合框架练习题等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Java里面的数组数据可以通过索引来获取,那么对象呢?也是通过索引吗?今天我们就来分析一下Java集合中获取集合对象的方法迭代-Iterator。

本篇文章主要分析一下Java集合框架中的迭代器部分,Iterator,该源码分析基于JDK1.8,分析工具,AndroidStudio,文章分析不足之处,还请指正!

一、简介

我们常常使用 JDK 提供的迭代接口进行 Java 集合的迭代。

 Iterator iterator = list.iterator();
      while(iterator.hasNext()){
        String string = iterator.next();
        //do something
      }
</div>

上面便是迭代器使用的基本模板,迭代其实我们可以简单地理解为遍历,是一个标准化遍历各类容器里面的所有对象的方法类。它总是控制 Iterator,向它发送”向前”,”向后”,”取当前元素”的命令,就可以间接遍历整个集合。在 Java 中 Iterator 为一个接口,它只提供了迭代了基本规则:

  public interface Iterator<E> {
  //判断容器内是否还有可供访问的元素
  boolean hasNext();
  //返回迭代器刚越过的元素的引用,返回值是 E
  E next();
  //删除迭代器刚越过的元素
  default void remove() {
    throw new UnsupportedOperationException("remove");
  }
}
</div>

上面便是迭代器的基本申明,我们通过具体的集合来分析。

二、集合分类

2.1 ArrayList的Iterator

我们通过分析ArrayList的源码可以知道,在 ArrayList 内部首先是定义一个内部类 Itr,该内部类实现 Iterator 接口,如下:

private class Itr implements Iterator<E> {
  //....
}
</div>

在内部类实现了Iterator接口,而ArrayList的Iterator是返回的它的内部类Itr,所以我们主要看看Itr是如何实现的。

  public Iterator<E> iterator() {
    return new Itr();
  }
</div>

接下来我们分析一下它的内部类Itr的实现方式。

  private class Itr implements Iterator<E> {

    protected int limit = ArrayList.this.size;

    int cursor;    // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    public boolean hasNext() {
      return cursor < limit;
    }

    @SuppressWarnings("unchecked")
    public E next() {
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      int i = cursor;
      if (i >= limit)
        throw new NoSuchElementException();
      Object[] elementData = ArrayList.this.elementData;
      if (i >= elementData.length)
        throw new ConcurrentModificationException();
      cursor = i + 1;
      return (E) elementData[lastRet = i];
    }

    public void remove() {
      if (lastRet < 0)
        throw new IllegalStateException();
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();

      try {
        ArrayList.this.remove(lastRet);
        cursor = lastRet;
        lastRet = -1;
        expectedModCount = modCount;
        limit--;
      } catch (IndexOutOfBoundsException ex) {
        throw new ConcurrentModificationException();
      }
    }

    @Override
    @SuppressWarnings("unchecked")
    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;

      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
    }
  }

</div>

首先我们来分析一下定义的变量:

    protected int limit = ArrayList.this.size;

    int cursor;    // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

</div>

其中,limit是当前ArrayList的大小,cursor代表的是下一个元素的索引,而lastRet是上一个元素的索引,没有的话就返回-1,expectedModCount没什么多大用处。我们接着分析看迭代的时候怎么判断有没有后继元素的。

  public boolean hasNext() {
      return cursor < limit;
  }
</div>

很简单,就是判断下一个元素的索引有没有到达数组的容量大小,达到了就没有了,到头了!

接着,我们在分析一下获取当前索引的元素的方法next

    public E next() {
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      int i = cursor;
      if (i >= limit)
        throw new NoSuchElementException();
      Object[] elementData = ArrayList.this.elementData;
      if (i >= elementData.length)
        throw new ConcurrentModificationException();
      cursor = i + 1;
      return (E) elementData[lastRet = i];
    }
</div>

在next方法中为什么要判断modCount呢?即用来判断遍历过程中集合是否被修改过。modCount 用于记录 ArrayList 集合的修改次数,初始化为 0,,每当集合被修改一次(结构上面的修改,内部update不算),如 add、remove 等方法,modCount + 1,所以如果 modCount 不变,则表示集合内容没有被修改。该机制主要是用于实现 ArrayList 集合的快速失败机制,在 Java 的集合中,较大一部分集合是存在快速失败机制的。所以要保证在遍历过程中不出错误,我们就应该保证在遍历过程中不会对集合产生结构上的修改(当然 remove 方法除外),出现了异常错误,我们就应该认真检查程序是否出错而不是 catch 后不做处理。上面的代码比较简单,就是返回索引处的数组值。

对于ArrayList的迭代方法,主要是判断索引的值和数组的大小进行比较,看看还没有数据可以遍历了,然后再依次获取数组中的值,而已,主要抓住各个集合的底层实现方式即可进行迭代。

接下来我们在分析一下HashMap的Iterator的方法,其他方法类似,只要抓住底层实现方式即可。

2.2 HashMap的Iterator

在HashMap中,也有一个类实现了Iterator接口,只不过是个抽象类,HashIterator,我们来看看它的实现方式。

 private abstract class HashIterator<E> implements Iterator<E> {
    HashMapEntry<K,V> next;    // next entry to return
    int expectedModCount;  // For fast-fail
    int index;       // current slot
    HashMapEntry<K,V> current;   // current entry

    HashIterator() {
      expectedModCount = modCount;
      if (size > 0) { // advance to first entry
        HashMapEntry[] t = table;
        while (index < t.length && (next = t[index++]) == null)
          ;
      }
    }

    public final boolean hasNext() {
      return next != null;
    }

    final Entry<K,V> nextEntry() {
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      HashMapEntry<K,V> e = next;
      if (e == null)
        throw new NoSuchElementException();

      if ((next = e.next) == null) {
        HashMapEntry[] t = table;
        while (index < t.length && (next = t[index++]) == null)
          ;
      }
      current = e;
      return e;
    }

    public void remove() {
      if (current == null)
        throw new IllegalStateException();
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      Object k = current.key;
      current = null;
      HashMap.this.removeEntryForKey(k);
      expectedModCount = modCount;
    }
  }

</div>

同样,

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Java中的对象和引用详解
  • java回调机制实例详解
  • Java实现一个达达租车系统的步骤详解
  • Java 7大常见排序方法实例详解
  • 详解JAVA的封装
  • Java集合框架LinkedList详解及实例
  • Java集合框架中迭代器Iterator解析
  • Java 读取外部资源的方法详解及实例代码
  • Java实现一个达达租车系统的步骤详解
  • Java 7大常见排序方法实例详解

相关文章

  • 2017-05-28java 数据的加密与解密普遍实例代码
  • 2017-05-28Java Map简介_动力节点Java学院整理
  • 2017-05-28SpringBoot整合JPA的实例代码
  • 2017-05-28java枚举类的构造函数实例详解
  • 2017-05-28Java本地缓存的实现代码
  • 2017-05-28java中的Struts2拦截器详解
  • 2017-05-28Spring Boot 集成MyBatis 教程详解
  • 2017-05-28Java定时器例子_动力节点Java学院整理
  • 2017-05-28Java集合框架中迭代器Iterator解析
  • 2017-05-28详解前后端分离之Java后端

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • ByteArrayInputStream简介和使用_动力节点Java学院整理
    • Spring MVC配置双数据源实现一个java项目同时连接两个数据库的方法
    • SWT(JFace)体验之ProgressBar
    • 深入理解java泛型详解
    • java 算法之希尔排序详解及实现代码
    • Java LocalCache 本地缓存的实现实例
    • Spring MVC登录注册以及转换json数据
    • java读取某个文件夹下的所有文件实例代码
    • Java中网络IO的实现方式(BIO、NIO、AIO)介绍
    • Java SpringMVC实现国际化整合案例分析(i18n)

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有