Iterator 和 Iterable 区别和联系
首先预览下Java源码中的Iterator和Iterable:
Iterable接口:
public interface Iterable<T> {//这里只摘录接口中的抽象方法
/**
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
Iterator<T> iterator();
}
Iterator接口:
public interface Iterator<E> {
/**
* Returns {@code true} if the iteration has more elements.
* (In other words, returns {@code true} if {@link #next} would
* return an element rather than throwing an exception.)
*
* @return {@code true} if the iteration has more elements
*/
boolean hasNext();
/**
* Returns the next element in the iteration.
*
* @return the next element in the iteration
* @throws NoSuchElementException if the iteration has no more elements
*/
E next();
}
用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 接口。
public interface Collection<E> extends Iterable<E> { }
而在具体的实现类中(比如 ArrayList),则在内部维护了一个 Itr 内部类,该类继承了 Iterator 接口,它的hasNext() 和 next() 方法是和 ArrayList 实现相耦合的。当调用 ArrayList 对象的 iterator() 方法的时候,返回该类 Itr 的一个实例,从而实现遍历 ArrayList 的功能。
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
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 != 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();
}
}
在遍历元素或者删除元素时,必须要进行next()方法,要不然,迭代器不能正常运行:如
Iterator 和 Iterable 区别和联系的更多相关文章
- 大杂烩 -- Iterator 和 Iterable 区别和联系
基础大杂烩 -- 目录 用Iterator模式实现遍历集合 Iterator模式是用于遍历集合类的标准访问方法.它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构. 例 ...
- java中的Iterator和Iterable 区别
java.lang.Iterable java.util.Iterator 来自百度知道: Iterator是迭代器类,而Iterable是接口. 好多类都实现了Iterable接口,这样对象就可以调 ...
- 分享知识-快乐自己:JAVA中的 Iterator 和 Iterable 区别
java.lang.Iterable java.util.Iterator Iterator是迭代器类,而Iterable是接口. 好多类都实现了Iterable接口,这样对象就可以调用itera ...
- Iterator和Iterable的区别以及使用
Iterator和Iterable的区别以及使用 1.什么是迭代器 迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址.迭代 ...
- iterator与iterable的区别和联系
iterator与iterable 用Iterator模式实现遍历集合Iterator模式是用于遍历集合类的标准访问方法.它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内 ...
- iterator和iterable的区别
相关博客: http://blog.csdn.net/lipengcn/article/details/51700153 Java中Iterable和Iterator的辨析 http ...
- 【转】Java迭代:Iterator和Iterable接口
Java迭代 : Iterator和Iterable接口 从英文意思去理解 Iterable :故名思议,实现了这个接口的集合对象支持迭代,是可迭代的.able结尾的表示 能...样,可以做.... ...
- python generator iterator和iterable object
1 iterable object list.dict.set.tuple.file(在每行上iterate)等都是iterable object,但是它们不是iterator.但是它们可以转换成it ...
- 【转】Python 中 Iterator和Iterable的区别
Python中 list,truple,str,dict这些都可以被迭代,但他们并不是迭代器.为什么? 因为和迭代器相比有一个很大的不同,list/truple/map/dict这些数据的大小是确定的 ...
随机推荐
- dvi 中的内容居中
text-align:right; 文本居中 line-height:35px;*垂直居中*
- VMware ESXi 不支持NTFS格式的USB外接硬盘
本来想搞直通USB外接大容量硬盘(希捷Seagate Backup+ Hub WH 8T),实现在同一部ESXi下,直接将NAS的数据转移到外接硬盘.结果发现虚拟机下的win server系统识别不了 ...
- selenium测试(Java)-- 一组元素操作(十一)
利用下面的例子来编写测试脚本 页面代码: <!DOCTYPE html> <html> <head> <meta http-equiv="conte ...
- 第二百八十二节,MySQL数据库-MySQL视图
MySQL数据库-MySQL视图 1.视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. 2.也 ...
- 关于IFrame表述正确的有:()
A. 通过IFrame,网页可以嵌入其他网页内容,并可以动态更改 B. 在相同域名下,内嵌的IFrame可以获取外层网页的对象 C. 在相同域名下,外层网页脚本可以获取IFrame网页内的对象 D. ...
- WF4.0——升级技能:泛型应用
前提: 在项目的开发中.我们知道,增加泛型,通过对类型的封装,进行抽象后.能够大大降低我们代码量,在项目中,泛型能够说是高级project师必备的技能之中的一个.也是面向对象的核心"抽象&q ...
- DB2多行转一行【XML方式】
分组然后合并,然后去除XML标签 SELECT replace(replace(replace(xml2clob(xmlagg(xmlelement(name A, [字段]))),'</A&g ...
- Apache 运行PHP原理
php,apache和mysql组合的工作过程: PHP的所有应用程序都是通过WEB服务器(如IIS或Apache)和PHP引擎程序解释执行完成的,工作过程: (1)当用户在浏览器地址中输入要访问的P ...
- sp_configure命令开启组件Agent XPs,数据库计划(Maintenance Plan)
新建“计划(Maintenance Plan)”时,记得执行计划需把SQL的“代理服务(SQL Server Agent)”也开启 出现对话框:“SQL Server 阻止了对组件 'Agent XP ...
- kafka学习之-文件存储机制
Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx ...