Java中Iterator(迭代器)实现原理
在Java中遍历List时会用到Java提供的Iterator,Iterator十分好用,原因是:
迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
Java中的Iterator功能比较简单,并且只能单向移动:
(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
(2) 使用next()获得序列中的下一个元素。
(3) 使用hasNext()检查序列中是否还有元素。
(4) 使用remove()将迭代器新返回的元素删除。
只要看看下面这个例子就一清二楚了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import java.util.*; public class Muster { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add( "a" ); list.add( "b" ); list.add( "c" ); Iterator it = list.iterator(); while (it.hasNext()){ String str = (String) it.next(); System.out.println(str); } } } |
运行结果:
a
b
c
可以看到,Iterator可以不用管底层数据具体是怎样存储的,都能够通过next()遍历整个List。
但是,具体是怎么实现的呢?背后机制究竟如何呢?
这里我们来看看Java里AbstractList实现Iterator的源代码:
1 . public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { // List接口实现了Collection<E>, Iterable<E> 2 . 3 . protected AbstractList() { 4 . } 5 . 6 . ... 7 . 8 . public Iterator<E> iterator() { 9 . return new Itr(); // 这里返回一个迭代器 10 . } 11 . 12 . private class Itr implements Iterator<E> { // 内部类Itr实现迭代器 13 . 14 . int cursor = 0 ; 15 . int lastRet = - 1 ; 16 . int expectedModCount = modCount; 17 . 18 . public boolean hasNext() { // 实现hasNext方法 19 . return cursor != size(); 20 . } 21 . 22 . public E next() { // 实现next方法 23 . checkForComodification(); 24 . try { 25 . E next = get(cursor); 26 . lastRet = cursor++; 27 . return next; 28 . } catch (IndexOutOfBoundsException e) { 29 . checkForComodification(); 30 . throw new NoSuchElementException(); 31 . } 32 . } 33 . 34 . public void remove() { // 实现remove方法 35 . if (lastRet == - 1 ) 36 . throw new IllegalStateException(); 37 . checkForComodification(); 38 . 39 . try { 40 . AbstractList. this .remove(lastRet); 41 . if (lastRet < cursor) 42 . cursor--; 43 . lastRet = - 1 ; 44 . expectedModCount = modCount; 45 . } catch (IndexOutOfBoundsException e) { 46 . throw new ConcurrentModificationException(); 47 . } 48 . } 49 . 50 . final void checkForComodification() { 51 . if (modCount != expectedModCount) 52 . throw new ConcurrentModificationException(); 53 . } 54 . } 55 .} |
可以看到,实现next()是通过get(cursor),然后cursor++,通过这样实现遍历。
这部分代码不难看懂,唯一难懂的是remove操作里涉及到的expectedModCount = modCount;
在网上查到说这是集合迭代中的一种“快速失败”机制,这种机制提供迭代过程中集合的安全性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import java.util.*; public class Muster { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add( "a" ); list.add( "b" ); list.add( "c" ); Iterator it = list.iterator(); while (it.hasNext()){ String str = (String) it.next(); System.out.println(str); list.add( "s" ); //添加一个add方法 } } } |
运行结果:
a
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at com.hasse.Muster.main(Muster.java:11)
Java中Iterator(迭代器)实现原理的更多相关文章
- Java中Iterator(迭代器)的用法及其背后机制的探究
在Java中遍历List时会用到Java提供的Iterator,Iterator十分好用,原因是: 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结 ...
- 深入理解Java中的迭代器
迭代器模式:就是提供一种方法对一个容器对象中的各个元素进行访问,而又不暴露该对象容器的内部细节. 概述 Java集合框架的集合类,我们有时候称之为容器.容器的种类有很多种,比如ArrayList.Li ...
- Java中Iterator类的详细介绍
迭代器模式:就是提供一种方法对一个容器对象中的各个元素进行访问,而又不暴露该对象容器的内部细节. 概述 Java集合框架的集合类,我们有时候称之为容器.容器的种类有很多种,比如ArrayList.Li ...
- 从虚拟机指令执行的角度分析JAVA中多态的实现原理
从虚拟机指令执行的角度分析JAVA中多态的实现原理 前几天突然被一个"家伙"问了几个问题,其中一个是:JAVA中的多态的实现原理是什么? 我一想,这肯定不是从语法的角度来阐释多态吧 ...
- 自己实现java中Iterator(迭代器功能)
今天躺在床上忽然想到一个问题,迭代器的代码是如何实现的?于是乎不由自主的爬起来敲两行代码. List<String> list=new ArrayList<>(2); list ...
- 谈谈知识的融会贯通:以“java中的迭代器失效问题”为例
提示 文中涉及知识点: Collection . Iterator Guava 中的 Lists.partition 方法 如果你对这两个知识点不了解,强烈建议阅读文中引用的参考文章. 场景一:以Ar ...
- 大杂烩 -- Java中Iterator的fast-fail分析
基础大杂烩 -- 目录 Java中的Iterator非常方便地为所有的数据源提供了一个统一的数据读取(删除)的接口,但是新手通常在使用的时候容易报如下错误ConcurrentModificationE ...
- Java集合Iterator迭代器的实现
一.迭代器概述 1.什么是迭代器? 在Java中,有很多的数据容器,对于这些的操作有很多的共性.Java采用了迭代器来为各种容器提供了公共的操作接口.这样使得对容器的遍历操作与其具体的底层实现相隔离, ...
- Java之iterator迭代器和iterable接口
java.lang.Iterable java.util.Iterator Iterator是迭代器类,而Iterable是接口. 好多类都实现了Iterable接口,这样对象就可以调用iterato ...
随机推荐
- CentOS6— Redis安装(转和延续)
Part I. Redis安装(转载部分) 一.安装(官网地址 http://redis.io/download) wget http://download.redis.io/redis-stable ...
- 【CF666E】Forensic Examination
题解: 熟练掌握了后缀自动机后大部分题目应该都比较容易想 首先对t建立广义后缀自动机 然后我们可以用线段树合并处理出每个点每个串出现的次数,然后求出最大值 匹配的时候比较巧妙 我们离线处理 对于同一个 ...
- C语言整理——文件系统和文件访问
标准C中规定了文件系统的访问和对文件本身的访问.不管是windows系统或者是泛unix系统,都实现了这些接口.在了解这些知识后,跨平台编程也将非常容易. 对文件系统的访问接口有: chdrive() ...
- Codeforces 1045D Interstellar battle 概率期望
原文链接https://www.cnblogs.com/zhouzhendong/p/CF1045D.html 题目传送门 - CF1045D 题意 给定一棵有 $n$ 个节点的树,第 $i$ 个节点 ...
- BZOJ3437 小P的牧场 动态规划 斜率优化
原文链接http://www.cnblogs.com/zhouzhendong/p/8696321.html 题目传送门 - BZOJ3437 题意 给定两个序列$a,b$,现在划分$a$序列. 被划 ...
- byte数据常量池问题
[代码] public class BufferPoolDemo { public static void main(String[] args) { Integer i1=127; Integer ...
- Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第七集之SSH远程连接——克隆与更改配置】
一.SSH远程连接 OpenSSH的安装 查看是否安装Openssh:rpm -qa | grep ssh搜索openssh安装包:yum search openssh安装openssh:yum in ...
- 044 SimpleDateFormat的线程安全问题与解决方案
这个问题,以前好像写过,不过现在这篇文章,有一个重现的过程,还是值得读一读的. URL:SimpleDateFormat的线程安全问题与解决方案
- Raspberry 音乐播放器omxplayer安装
首先需要安装的是omxplayer播放器的依赖的库文件: wget http://pexpect.sourceforge.net/pexpect-2.3.tar.gz tar xzf pexpect- ...
- POJ 2455 Secret Milking Machine 【二分】+【最大流】
<题目链接> 题目大意: FJ有N块地,这些地之间有P条双向路,每条路的都有固定的长度l.现在要你找出从第1块地到第n块地的T条不同路径,每条路径上的路段不能与先前的路径重复,问这些路径中 ...