迭代器模式 -- Iterator

2017-04-09 22:53:17   最后更新: 2017-04-09 22:53:17   访问数量:352




其实各种面向对象编程语言大多提供了迭代器模式的实现和具体的工具类

迭代器模式主要是提供一种顺序访问一个聚合对象中的各个元素的方法,而不需要关心具体对象的类型和内部表示,在有些语言中,也被称为“游标”(Cursor)

容器以某种方式实现了一系列对象的聚合的同时通常必须要提供容器中元素的遍历和访问方式,而元素的访问时与容器的内部结构无关的,并且遍历操作应该是抽象且可以针对各种不同的容器的,迭代器就解决了这个问题

迭代器模式将对列表的访问和遍历取出的对象放入一个迭代器对象中,从而实现对遍历到的元素的跟踪

迭代器模式让列表的遍历操作与列表本身分离,这样我们可以轻易的实现不同的遍历策略,例如你只想访问列表中某些你关心的数据

但是,根据上述的描述,迭代器与被遍历的列表是耦合的,也就是说每一个列表需要一个特定的迭代器,解决这个问题的方法通常是让多个列表继承一个抽象列表类,而多个迭代器继承自一个抽象的 Iterator 类,这样就是一个多态迭代器,从而实现了迭代机制与具体聚合类的解耦

 

  1. 需要访问一个聚合对象的内容而无需暴露这个聚合对象的内部表示
  2. 支持对聚合对象的多种遍历方式
  3. 为遍历不同的聚合结构提供一个统一的接口

 

 

 

如上图所示,迭代器模式主要有以下组件构成:

  • Iterator -- 迭代器定义访问和遍历元素的接口
  • ConcreteIterator -- Iterator 接口的具体实现类,用于跟踪对应聚合对象遍历时的当前位置
  • Aggregate -- 被遍历集合的抽象类
  • ConcreteAggregate -- 实现 Aggregate 的具体聚合类,提供创建对应迭代器的接口

 

  1. 迭代器模式支持以不同的方式遍历一个集合,例如树状结构等复杂的集合通常可以用多种方式进行遍历,而迭代器模式使得改变遍历算法变得容易,仅需用一个不同的迭代器类实例代替原有实例即可
  2. 迭代器简化了集合的接口,集合不在需要为每一种遍历方式均提供接口
  3. 集合无需保持自己的遍历状态,这样就可以同时进行多个遍历了

 

内部迭代器与外部迭代器

迭代器模式通常有两种实现方式 -- 外部迭代器与内部迭代器

外部迭代器指的是有 client 主动调用迭代器对象提供的某个方法,从而推进遍历操作的继续进行

而内部迭代器则是 client 只需要提供一个具体的待执行操作,由迭代器自动将该操作应用于集合中的全部元素

显然,外部迭代器要比内部迭代器更加灵活,这也是大多数面向对象实现迭代器的主要方式

然而,对于 Composite 模式中的那些递归集合的遍历,外部迭代器是难以实现的,因为对象必须处于嵌套集合的多个不同的层次上,要遍历这样的树状结构,迭代器需要记录一条遍历路径,而使用内部迭代器就要容易的多,迭代器只要递归调用自己即可

 

迭代器与游标

迭代器通常实现了 next() 操作,从而让用户可以主动触发遍历的进行,迭代器负责遍历算法将易于在相同集合上使用不同的遍历算法

但是有时,迭代器的 next 操作是通过直接调用集合的 next 操作实现的,这样,实际进行迭代操作的是集合本身,这样的迭代器被称为“游标”,这样实现的好处是可以在操作的过程中访问集合的私有成员,如果集合的私有成员可以被迭代器访问,那么这将破坏集合的封装性

 

java 中的 Iterator 是一个接口:

Package java.util; publicinterface Iterator<E> { boolean hasNext(); //判断是否存在下一个对象元素 E next(); void remove(); }

 

你可以使用各个容器的 iterator() 方法获取容器对应的迭代器对象,也可以通过实现 Iterator 接口创建自己的迭代器类

 

jdk 1.5 引入了 foreach 循环:

java5 新特性

java 的 foreach 循环提供了非常简洁的遍历操作的实现,而实际上他就是通过迭代器实现的

但是,需要注意的是,如果在循环中调用集合的 remove 方法,那么 foreach 循环将会出错,但是直接使用 Iterator 或 for 循环,调用 remove() 方法则不会出错

 






技术帖      龙潭书斋      java      面向对象      oop      foreach      设计模式      design pattern      迭代器      迭代器模式      for      循环      遍历     


京ICP备15018585号