大杂烩 -- Iterator 和 Iterable 区别和联系
基础大杂烩 -- 目录
用Iterator模式实现遍历集合
Iterator模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。
例如,如果没有使用Iterator,遍历一个数组的方法是使用索引: for(int i=0; i<array.size(); i++) { ... get(i) ... }
而访问一个链表(LinkedList)又必须使用while循环: while((e=e.next())!=null) { ... e.data() ... }
以上两种方法客户端都必须事先知道集合的内部结构,访问代码和集合本身是紧耦合,无法将访问逻辑从集合类和客户端代码中分离出来,每一种集合对应一种遍历方法,客户端代码无法复用。
更恐怖的是,如果以后需要把ArrayList更换为LinkedList,则原来的客户端代码必须全部重写。
解决以上问题,Iterator模式总是用同一种逻辑来遍历集合: for(Iterator it = c.iterater(); it.hasNext(); ) { ... }
奥秘在于客户端自身不维护遍历集合的"指针",所有的内部状态(如当前元素位置,是否有下一个元素)都由Iterator来维护,而这个Iterator由集合类通过工厂方法生成,因此,它知道如何遍历整个集合。
客户端从不直接和集合类打交道,它总是控制Iterator,向它发送"向前","向后","取当前元素"的命令,就可以间接遍历整个集合。
首先看看Java.util.Iterator接口的定义:
public interface Iterator { boolean hasNext(); Object next(); void remove(); }
依赖前两个方法就能完成遍历,典型的代码如下:
for(Iterator it = c.iterator(); it.hasNext(); ) { Object o = it.next(); // 对o的操作... }
每一种集合类返回的Iterator具体类型可能不同,Array可能返回ArrayIterator,Set可能返回 SetIterator,Tree可能返回TreeIterator,但是它们都实现了Iterator接口,因此,客户端不关心到底是哪种 Iterator,它只需要获得这个Iterator接口即可,这就是面向对象的威力。
所有集合类都实现了 Collection 接口,而 Collection 继承了 Iterable 接口。
/** * Implementing this interface allows an object to be the target of * the "foreach" statement. * * @param <T> the type of elements returned by the iterator * * @since 1.5 */ public interface Iterable<T> { /** * Returns an iterator over a set of elements of type T. * * @return an Iterator. */ Iterator<T> iterator(); }
而在具体的实现类中(比如 ArrayList),则在内部维护了一个 Itr 内部类,该类继承了 Iterator 接口,它的hasNext() 和 next() 方法是和 ArrayList 实现相耦合的。当调用 ArrayList 对象的 iterator() 方法的时候,返回该类 Itr 的一个实例,从而实现遍历 ArrayList 的功能。
/*** Returns an iterator over the elements in this list in proper sequence.** <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.** @return an iterator over the elements in this list in proper sequence*/public Iterator<E> iterator() {return new Itr();}/*** An optimized version of AbstractList.Itr*/private class Itr implements Iterator<E> {int cursor; // index of next element to returnint lastRet = -1; // index of last element returned; -1 if no suchint expectedModCount = modCount;public boolean hasNext() {return cursor != size;}@SuppressWarnings("unchecked")public E next() {checkForComodification();int i = cursor;if (i >= size)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();checkForComodification();try {ArrayList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = modCount;} 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 trafficcursor = i;lastRet = i - 1;checkForComodification();}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}
为什么一定要去实现Iterable这个接口呢?为什么不直接实现Iterator接口呢?
看一下JDK中的集合类,比如List一族或者Set一族,都是实现了Iterable接口,但并不直接实现Iterator接口。 仔细想一下这么做是有道理的。
因为Iterator接口的核心方法next()或者hasNext() 是依赖于迭代器的当前迭代位置的。 如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。 当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。 除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。 但即时这样,Collection也只能同时存在一个当前迭代位置。 而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器。 多个迭代器是互不干扰的。
啦啦啦
转载于:https://www.cnblogs.com/ClassNotFoundException/p/7092041.html
大杂烩 -- Iterator 和 Iterable 区别和联系相关推荐
- java中的Iterator和Iterable 区别
原文:http://perfy315.iteye.com/blog/1459201 ---------------------------------------------------------- ...
- 【JDK源码】Iterator与Iterable的实现与区别
–本文前言– 在介绍Iterator与Iterable接口之前,需要了解Iterator与Iterable接口在Java类库家族谱中的地位.如下图0-1所示. [版权声明]归CSDN账 ...
- java iterable和iterator_在Java中将Iterator转换为Iterable
假设以下是具有整数值的迭代器-Iterator iterator = Arrays.asList(20, 40, 60, 80, 100, 120, 150, 200).iterator(); 现在, ...
- Python 中 Iterator和Iterable的区别
Python中 list,truple,str,dict这些都可以被迭代,但他们并不是迭代器.为什么? 因为和迭代器相比有一个很大的不同,list/truple/map/dict这些数据的大小是确定的 ...
- python iterator iterable_Python中Iterator和Iterable的区别
python中list, str,truple, dict都是可以被迭代的,但他们不是迭代器.why? list/truple/map/dict这些数据的大小是确定的,我们可以准确知道他们的size ...
- Iterator 和 Iterable的区别
1.Collection实现了Itarable接口,这是为了给其子类提供规范的遍历方法,比如ArrayList使用数组存储,HashSet使用散列存储,其遍历方法肯定是不一致的,要求所有子类实现统一的 ...
- java--迭代(一)Iterator和Iterable接口
摘自:http://www.cnblogs.com/redcoatjk/articles/4863340.html Iterable:顾名思义,实现了这个接口的对象支持迭代,是可迭代的. Iterat ...
- Iterator、Iterable接口的使用及详解
Java集合类库将集合的接口与实现分离.同样的接口,可以有不同的实现. Java集合类的基本接口是Collection接口.而Collection接口必须实现Iterator接口. 以下图表示集合框架 ...
- iterator与iterable
用Iterator模式实现遍历集合 Iterator模式是用于遍历集合类的标准访问方法.它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构. 例如,如果没有使用Itera ...
- java中iterable_java中的Iterator和Iterable
1.Iterable接口在java.lang包中:Iterator接口在java.util包中 2.Iterable中只有一个方法,那就是返回一个Iterator迭代器:Iterator iterat ...
最新文章
- 漫画:HTTP之大明邮差
- TensorFlow 官方文档中文版发布啦(持续维护)
- 4.10 风格代价函数-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
- oracle pl/sql 中目录的创建
- 算法练习day1——190318(二分查找)
- 单片机方波幅度调节c语言,为什么我用单片机做的频率可调的方波输出会有尖刺,而且会断...
- MyBatis基础知识概述
- 定义python函数时如果没有return_定义 Python 函数时,如果函数中没有 return 语句,则默认返回空值 None 。_学小易找答案...
- eclipse get set 自动添加注释
- java作业——Day0014
- 解决iPhone、iPad 或 iPod touch 无法连接Wi-Fi网络问题
- 如何在 CSS 中将表格居中?
- win7 按修改时间范围文件搜索
- 银河麒麟Kylin_s10_sp3安装Oracle11g(FS)(官方补丁认证)(亲测有效)
- iPhone14pro紫色“掉漆”/ 苹果英伟达拒绝台积电涨价/ DALL·E取消排队...今日更多新鲜事在此...
- ARM与DSP的区别
- 视频加密选择在线加密还是软件加密好?
- 苹果呼叫转移设置不了_苹果手机也可以开启电信VoLTE!
- Matlab figure去白边
- ImageNet1K的下载与使用
热门文章
- Linux编译错误:对‘sem_init/sem_wait/sem_destroy’等未定义的引用
- 字符串 -- 3.1 Valid Palindrome -- 图解
- 阅读分布式锁文章总结
- ajax 保存xmldoc对象,AJAX XML 实例
- 数据库与表的操作之创建表(CREATE TABLE)
- 【渝粤教育】国家开放大学2018年春季 7392-21FMatlab语言及其应用 参考试题
- [渝粤教育] 西南科技大学 管理学原理 在线考试复习资料(4)
- 数据预处理第7讲:具有离群点数据的缩放方法比较
- C语言获取系统时间的几种方式 !
- JavaScript中的数据类型和数据类型转换