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的操作... } 
在JDK1.5中,还对上面的代码在语法上作了简化(但是限于只读,如果需要remove,还是直接使用iterator):
// Type是具体的类型,如String。 for(Type t : c) { // 对t的操作... } 
每一种集合类返回的Iterator具体类型可能不同,Array可能返回ArrayIterator,Set可能返回SetIterator,Tree可能返回TreeIterator,但是它们都实现了Iterator接口,因此,客户端不关心到底是哪种Iterator,它只需要获得这个Iterator接口即可,这就是面向对象的威力。

----------------------------------------------------------------

在遍历的过程中出现java.util.ConcurrentModificationException的问题参http://www.blogjava.net/EvanLiu/archive/2008/08/31/224453.html

用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的操作... } 
在JDK1.5中,还对上面的代码在语法上作了简化(但是限于只读,如果需要remove,还是直接使用iterator):
// Type是具体的类型,如String。 for(Type t : c) { // 对t的操作... } 
每 一种集合类返回的Iterator具体类型可能不同,Array可能返回ArrayIterator,Set可能返回SetIterator,Tree可 能返回TreeIterator,但是它们都实现了Iterator接口,因此,客户端不关心到底是哪种Iterator,它只需要获得这个 Iterator接口即可,这就是面向对象的威力。

----------------------------------------------------------------

在遍历的过程中出现java.util.ConcurrentModificationException的问题参http://www.blogjava.net/EvanLiu/archive/2008/08/31/224453.html

如果想用foreach遍历自定义类的集合,自定义类通常需要实现implement iterable接口. 该接口定义了Iterator<T> iterator()方法. 有些时候这个iterator方法可以供用类里面的集合属性.iterator()返回.

示例:

 public class Teacher implements Iterable{  

     private String name;  
private int age; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Iterator iterator() {
return new Itr();
} public static void main(String[] args) {
Teacher t = new Teacher();
t.setName("aaaaaaa");
t.setAge(23);
for (Object o : t) {
System.out.println(o.toString());
}
} private class Itr implements Iterator{
private int cursor=0; // 属性的索引
private Field[] fields = Teacher.class.getDeclaredFields(); // 属性的数组 public boolean hasNext() { return cursor!=(Teacher.class.getDeclaredFields().length);
} public Object next() {
Object o=null;
try{
fields[cursor].setAccessible(true); // 让内部类可以访问外部类的私有属性的值
o = fields[cursor].getName()+" "+fields[cursor].get(Teacher.this);
cursor++;
}catch(Exception e){
System.out.println(e);
} return o;
} public void remove() {
// TODO Auto-generated method stub } }
}

示例2:

import java.util.Iterator;

//测试类
public class Exec {
public static void main(String[] args) throws Exception {
// 创建学生集合类
Students students = new Students(10); // 通过for each语句迭代循环学生集合类的每个元素
for (Object obj : students) {
Student stu = (Student) obj;
System.out.println(stu.getSid() + ":" + stu.getName());
}
}
} // 支持for each迭代循环的学生集合类
class Students implements Iterable {
// 存储所有学生类的数组
private Student[] stus; // 该构造函数可以生成指定大小的学生类变量数组,并初始化该学生类变量数组
public Students(int size) {
stus = new Student[size];
for (int i = 0; i < size; i++) {
stus[i] = new Student(String.valueOf(i), "学生" + String.valueOf(i));
}
} // 实现Iterable接口的重要方法,返回自定义的迭代类变量
public Iterator iterator() {
return new StudentIterator();
} // 实现Iterator接口的私有内部类,外界无法直接访问
private class StudentIterator implements Iterator {
// 当前迭代元素的下标
private int index = 0; // 判断是否还有下一个元素,如果迭代到最后一个元素就返回false
public boolean hasNext() {
return index != stus.length;
} // 返回当前元素数据,并递增下标
public Object next() {
return stus[index++];
} // 这里不支持,抛出不支持操作异常
public void remove() {
throw new UnsupportedOperationException();
}
}
} // 学生类
class Student {
// 学生学号
private String sid; // 学生姓名
private String name; // 默认构造函数
public Student() {
} // 支持属性值初始化的构造函数
public Student(String sid, String name) {
setSid(sid);
setName(name);
} // 学生学号的读取函数
public String getSid() {
return sid;
} // 学生学号的设置函数
public void setSid(String sid) {
this.sid = sid;
} // 学生姓名的读取函数
public String getName() {
return name;
} // 学生姓名的设置函数
public void setName(String name) {
this.name = name;
} // 格式化字符信息输出
public String toString() {
return this.sid + ":" + this.name;
}
}

----------------------------------------------------------------------------

为什么一定要去实现Iterable这个接口呢? 为什么不直接实现Iterator接口呢?

看一下JDK中的集合类,比如List一族或者Set一族, 
都是实现了Iterable接口,但并不直接实现Iterator接口。 
仔细想一下这么做是有道理的。因为Iterator接口的核心方法next()或者hasNext() 
依赖于迭代器的当前迭代位置的。 
如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。 
当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。 
除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。 
但即时这样,Collection也只能同时存在一个当前迭代位置。 
而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器。 
多个迭代器是互不干扰的。

iterator与iterable的区别和联系的更多相关文章

  1. Iterator和Iterable的区别以及使用

    Iterator和Iterable的区别以及使用   1.什么是迭代器 迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址.迭代 ...

  2. iterator和iterable的区别

    相关博客:  http://blog.csdn.net/lipengcn/article/details/51700153         Java中Iterable和Iterator的辨析 http ...

  3. 【转】Python 中 Iterator和Iterable的区别

    Python中 list,truple,str,dict这些都可以被迭代,但他们并不是迭代器.为什么? 因为和迭代器相比有一个很大的不同,list/truple/map/dict这些数据的大小是确定的 ...

  4. Python 中 Iterator和Iterable的区别

    Python中 list,truple,str,dict这些都可以被迭代,但他们并不是迭代器.为什么? 因为和迭代器相比有一个很大的不同,list/truple/map/dict这些数据的大小是确定的 ...

  5. Iterator 和 Iterable 区别和联系

    首先预览下Java源码中的Iterator和Iterable: Iterable接口: public interface Iterable<T> {//这里只摘录接口中的抽象方法 /** ...

  6. for,foreach,iterator的用法和区别

    for,foreach,iterator的用法和区别 相同点:   三个都可以用来遍历数组和集合不同点:1.形式差别 for的形式是for(int i=0;i<arr.size();i++){. ...

  7. 14、Iterator跟ListIterator的区别

    14.Iterator与ListIterator的区别 在使用List,Set的时候,为了实现对其数据的遍历,会经常使用到Iterator(跌代器).使用跌代器,不需要干涉其遍历的过程,只需要每次取出 ...

  8. 【转】Java迭代:Iterator和Iterable接口

    Java迭代 : Iterator和Iterable接口 从英文意思去理解 Iterable :故名思议,实现了这个接口的集合对象支持迭代,是可迭代的.able结尾的表示 能...样,可以做.... ...

  9. Iterator 与ListIterator的区别

    Iterator 与ListIterator的区别: 1.Iterator能够迭代Set和List集合的元素,而ListIterator只能迭代List集合的元素 2.Iterator只能前向迭代,L ...

随机推荐

  1. arcgis10.0 切片并发布服务及验证

    1.切片参考网址:https://jingyan.baidu.com/article/fa4125accc6bef28ac7092d7.html 2.通过下面代码验证  参考网址https://www ...

  2. IdentityServer4 + SignalR Core +RabbitMQ 构建web即时通讯(一)

    IdentityServer4 + SignalR Core +RabbitMQ 构建web即时通讯 前言 .net core 2.1已经正式发布了,signalr core1.0随之发布,是时候写个 ...

  3. python 基础 7.2 时间格式的相互转换

    #/usr/bin/python #coding=utf-8 #@Time   :2017/11/9 8:55 #@Auther :liuzhenchuan #@File   :时间格式的相互转换.p ...

  4. LRM-00109: could not open parameter file

    SQL>startup                                                                                       ...

  5. 【题解】P4799[CEOI2015 Day2]世界冰球锦标赛

    [题解][P4799 CEOI2015 Day2]世界冰球锦标赛 发现买票顺序和答案无关,又发现\(n\le40\),又发现从后面往前面买可以通过\(M\)来和从前面往后面买的方案进行联系.可以知道是 ...

  6. import org.marker.weixin.DefaultSession; import org.marker.weixin.HandleMessageAdapter; import org.marker.weixin.MySecurity; import org.marker.weixin.msg.*;

    需要以下微信包可以添加我的微信公众号 回复“微信api”即可得到jar链接,以及maven添加本地jar方法,以及更改后的源代码 import org.marker.weixin.DefaultSes ...

  7. ruby 字符串

    字符串处理函数 1.返回字符串的长度 str.length => integer 2.判断字符串中是否包含另一个串 str.include? other_str => true or fa ...

  8. AppStore App申请审核加速

    容芳志大牛一直是我学习的榜样 分类: iOS开发经验技巧2014-11-12 09:40 409人阅读 评论(0) 收藏 举报 有没有遇到上线后发现很严重的bug这种情况,修复bug后提交审核又是漫长 ...

  9. Matlab图像处理(02)-图像基础

    数据类 Matlab中和IPT中支持的基本数据类型如下: 名称 描述 double 双精度浮点数,范围-10308~10308  8字节 uint8 无符号1字节整数,范围[0, 255] uint1 ...

  10. jquery.dataTables.min.js: Uncaught TypeError: Cannot read property 'style' of undefined

    原因:datatable表格内容有操作列,而表头没有定义操作列 少写了一行:<th>操作</th>