迭代器简述

迭代器原理与模式
转自:http://289196801.iteye.com/blog/1511867
在jdk中,与迭代器相关的接口有两个:Iterator 与 Iterable 

Iterator:迭代器,Iterator及其子类通常是迭代器本身的结构与方法; 
Iterable:可迭代的,那些想用到迭代器功能的其它类,如AbstractList HashMap等,需要实现该接口。 

以下为两个接口源码: 
Iterator 如下: 
Java代码  收藏代码
  1.    
  2. 1.public interface Iterator {    
  3. 2.    boolean hasNext();    
  4. 3.    E next();    
  5. 4.    void remove();    
  6. 5.}    

Iterable 如下: 
Java代码  收藏代码
  1. 1.public interface Iterable {    
  2. 2.    Iterator iterator();    
  3. 3.}    


看完源码,我们来看看迭代器是如何使用的: 
1. 若类A想要使用迭代器,则它的类声明部分为 class A implement Iterable 
2. 在类A实现中,要实现Iterable接口中的唯一方法:Iterator iterator(); 
   这个方法用于返回一个迭代器,即Iterator接口及其子类; 
3. 在类A中,定义一个内部类S,专门用于实现Iterator接口,定制类A自已的迭代器实现。 
如下: 
Java代码  收藏代码
  1. 1.class A implement Iterable    
  2. 2.{    
  3. 3.    Iterator iterator() {...}    
  4. 4.    class S implement Iterator     
  5. 5.    {    
  6. 6.        boolean hasNext() {....}    
  7. 7.        E next() {....}    
  8. 8.        void remove() {....}    
  9. 9.    }    
  10. 10.}    


我们再来看看jdk中是如何来使用的,如抽象类AbstractList: 
Java代码  收藏代码
  1. 1.public abstract class AbstractList extends AbstractCollection implements List { // List接口实现了Collection, Iterable   
  2. 2.    
  3. 3.    protected AbstractList() {    
  4. 4.    }    
  5. 5.      
  6. 6.    ...    
  7. 7.    
  8. 8.    public Iterator iterator() {    
  9. 9.    return new Itr();  // 这里返回一个迭代器  
  10. 10.    }    
  11. 11.    
  12. 12.    private class Itr implements Iterator {  // 内部类Itr实现迭代器  
  13. 13.         
  14. 14.    int cursor = 0;    
  15. 15.    int lastRet = -1;    
  16. 16.    int expectedModCount = modCount;    
  17. 17.    
  18. 18.    public boolean hasNext() {  // 实现hasNext方法  
  19. 19.            return cursor != size();    
  20. 20.    }    
  21. 21.    
  22. 22.    public E next() {  // 实现next方法  
  23. 23.            checkForComodification();    
  24. 24.        try {    
  25. 25.        E next = get(cursor);    
  26. 26.        lastRet = cursor++;    
  27. 27.        return next;    
  28. 28.        } catch (IndexOutOfBoundsException e) {    
  29. 29.        checkForComodification();    
  30. 30.        throw new NoSuchElementException();    
  31. 31.        }    
  32. 32.    }    
  33. 33.    
  34. 34.    public void remove() {  // 实现remove方法  
  35. 35.        if (lastRet == -1)    
  36. 36.        throw new IllegalStateException();    
  37. 37.            checkForComodification();    
  38. 38.    
  39. 39.        try {    
  40. 40.        AbstractList.this.remove(lastRet);    
  41. 41.        if (lastRet < cursor)    
  42. 42.            cursor--;    
  43. 43.        lastRet = -1;    
  44. 44.        expectedModCount = modCount;    
  45. 45.        } catch (IndexOutOfBoundsException e) {    
  46. 46.        throw new ConcurrentModificationException();    
  47. 47.        }    
  48. 48.    }    
  49. 49.    
  50. 50.    final void checkForComodification() {    
  51. 51.        if (modCount != expectedModCount)    
  52. 52.        throw new ConcurrentModificationException();    
  53. 53.    }    
  54. 54.    }    
  55. 55.}    



看完了迭代器,我们再看看迭代器模式: 
1. 提出问题:什么是迭代器模式? 为什么会有迭代器模式? 
   GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不 
                     需暴露该对象的内部细节。 
    我的理解: 就是把遍历算法从容器对象中独立出来,为什么要把遍历算从容器对象中独立 
              出来呢? 因为在面向对象设计中,一个难点就是辨认对象的职责。理想的状 
              态下,一个类应该只有一个单一的职责。职责分离可以最大限度的去耦合,但 
              是职责单一说起来容易,做起来难。具体到本模式,我们明显可以看到,一个 
              容器对象它提供了两个职责:一是组织管理数据对象,二是提供遍历算法。 
    所以:Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样 
         既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。 

2. 下面开始讲迭代器模式: 
   迭代器模式由以下角色组成: 
  1) 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。 
  2) 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并 
        要记录遍历中的当前位置。 
    3) 容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。 
  4) 具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色 
        的接口——这个具体迭代器角色于该容器的结构相关。 

    迭代器模式的类图如下: 
     
   
转自:http://289196801.iteye.com/blog/1511867
任务描述 相关知识 迭代器简述 定义迭代器 迭代器的基本操作 while 循环遍历迭代器 列表、数组转为迭代器 迭代器常用方法表 编程要求 测试说明 任务描述 本关任务:统计各单词长度。 相关知识 为了完成本关任务,你需要掌握: 1.什么是迭代器; 2.迭代器的基本操作。 迭代器简述 在 Scala 中,迭代器(Iterator)不是一个集合,而是构建了一种访问集合的方法。当构建一个集合需要很大的开销时(比如把文件得所有行都读取到内存),迭代器就发挥了很好的作用。迭代器有两个基本操作,next 和 hasNext。next 返回迭代器的下一个元素,hasNext 用于检查是否还有下一个元素。 定义迭代器 以下代码演示了如何定义迭代器。 object ForDemo { def main(args: Array[String]): Unit = { // 定义迭代器 var it=Iterator("edu","coder",1) } } 从上述代码中可以看出,使用 Iterator(元素 1,元素 2,...)即可定义一个迭代器,另外,它还可以存放不同数据类型的元素。 迭代器的基本操作 while 循环遍历迭代器迭代器逐个返回所有元素最简单的方法是使用 while 循环。 object Test { def main(args: Array[String]) { // 定义迭代器 val it = Iterator("百度", "腾讯", "阿里", "淘宝") // 遍历元素 while (it.hasNext){ println(it.next()) } } } 执行结果: 百度 腾讯 阿里 淘宝 上述代码中,it.hasNext 用于判断迭代器中是否还有下一个元素,如果有,返回 true,如果没有,返回 false。it.next 则用于获取下一个具体的值。 列表、数组转为迭代器 可以使用 toIterator 方法将数组或者列表转为迭代器。 object ForDemo { def main(args: Array[String]): Unit = { // 创建集合 val list=List(1,2,3) // 创建数组 val arr=Array(1,2,3) // 转为迭代器 var it=list.toIterator var it1=arr.toIterator // 遍历迭代器it的元素 while (it.hasNext){ println(it.next()) } // 遍历迭代器it1的元素 while (it1.hasNext){ println(it1.next()) } } } 执行结果: 1 2 3 1 2 3 迭代器常用方法表 下表列出了 Scala Iterator 常用的方法: 方法 描述 def hasNext: Boolean 如果还有可返回的元素,返回true def next(): A 返回迭代器的下一个元素,并且更新迭代器的状态 def ++(that: => Iterator[A]): Iterator[A] 合并两个迭代器 def ++[B >: A](that :=> GenTraversableOnce[B]): Iterator[B] 合并两个迭代器 def contains(elem: Any): Boolean 检测迭代器中是否包含指定元素 def copyToArray(xs: Array[A], start: Int, len: Int): Unit 将迭代器中选定的值传给数组 def count(p: (A) => Boolean): Int 返回迭代器元素中满足条件p的元素总数 def drop(n: Int): Iterator[A] 返回丢弃前n个元素新集合 def exists(p: (A) => Boolean): Boolean 返回一个布尔值,指明迭代器元素中是否存在满足p的元素 def filter(p: (A) => Boolean): Iterator[A] 返回一个迭代器 ,指向迭代器元素中所有满足条件p的元素 def flatMap[B](f: (A) => GenTraversableOnce[B]): Iterator[B] 针对迭代器的序列中的每个元素应用函数f,并返回指向结果序列的迭代器 def forall(p: (A) =>
最新发布
03-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值