1.什么是迭代器?
迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不用暴露该对象的内部表示。
举个例子:电视机有好多频道,电视机就是聚合对象。而我们看电视,不考虑你电视机里的频道内部如何,我们通过遥控器来调台。这个遥控器就是迭代器,我能看电视能调台,但是又不关注你电视机内部频道是怎么处理的。
迭代器模式又叫游标模式,是一种对象行为型模式
2.迭代器模式的结构
(1)Iterator(抽象迭代器):定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法
(2)ConcreteIterator(具体迭代器):实现了抽象迭代器,完成对聚合对象的遍历,同时在具体迭代器中通过游标来记录在聚合对象中所处的当前位置,再具体实现时游标通常是一个表示位置的非负整数
(3)Aggregate(抽象聚合类):存储和管理元素的对象,声明createIterator()方法创建一个迭代器对象,充当迭代器工厂
(4)ConcreteAggregate(具体聚合类):抽象聚合类的子类,实现createIterator()方法,返回一个与该具体聚合类对应的具体迭代器实例
3.迭代器模式实现
(1)抽象迭代器
/**
* 抽象迭代器
*/
public interface Iterator {
public void first();
public void next();
public boolean hasNext();
public Object currentItem();
}
(2)具体迭代器
/**
* 具体迭代器
*/
public class ConcreteIterator implements Iterator {
//维持一个对具体聚合对象的引用,以便访问存储在聚合对象中的数据
private ConcreteAggregate objects;
//维持一个游标,用于记录当前访问位置
private int cursor;
public ConcreteIterator(ConcreteAggregate objects){
this.objects = objects;
}
@Override
public void first() {
}
@Override
public void next() {
}
@Override
public boolean hasNext() {
return false;
}
@Override
public Object currentItem() {
return null;
}
}
(3)抽象聚合类,用于存储数据并创建迭代器对象
/**
* 抽象聚合类,用于存储数据并创建迭代器对象
*/
public interface Aggregate {
Iterator createIterator();
}
(4)具体聚合类,一方面负责存储数据,一方面实现createIterator()方法,用于返回一个具体迭代器对象
/**
* 具体聚合类,一方面负责存储数据,一方面实现createIterator()方法,用于返回一个具体迭代器对象
*/
public class ConcreteAggregate implements Aggregate {
@Override
public Iterator createIterator() {
return new ConcreteIterator(this);
}
4.迭代器模式实例——重构系统,将商品和客户等数据的存储和遍历分离
(1)抽象聚合类
/**
* 抽象聚合类
*/
public abstract class AbstractObjectList {
protected List<Object> objects = new ArrayList<Object>();
public AbstractObjectList(List<Object> objects){
this.objects = objects;
}
public void addObject(Object obj){
this.objects.add(obj);
}
public void removeObject(Object obj){
this.objects.remove(obj);
}
public List<Object> getObjects(){
return this.objects;
}
//声明创建迭代器对象的抽象工厂方法
public abstract AbstractIterator createIterator();
}
(2)商品数据类,充当具体聚合类
/**
* 商品数据类,充当具体聚合类
*/
public class ProductList extends AbstractObjectList {
public ProductList(List<Object> objects) {
super(objects);
}
//实现创建迭代器对象的具体工厂方法
@Override
public AbstractIterator createIterator() {
return new ProductIterator(this);
}
}
(3)抽象迭代器
/**
* 抽象迭代器
*/
public interface AbstractIterator {
public void next();//移至下一个元素
public void previous();//移至上一个元素
public boolean isLast();//判断是否为最后一个元素
public boolean isFirst();//判断是否为第一个元素
public Object getNextItem();//获取下一个元素
public Object getPreviousItem();//获取上一个元素
}
(4)商品迭代器,充当具体迭代器
/**
* 商品迭代器,充当具体迭代器
*/
public class ProductIterator implements AbstractIterator {
private List<Object> products;
private int cursor1;//定义一个游标,记录正向遍历的位置
private int cursor2;//定义一个游标,记录逆向遍历的位置
public ProductIterator(ProductList list){
this.products = list.getObjects();
cursor1 = 0;
cursor2 = products.size() - 1;
}
@Override
public void next() {
if(cursor1<products.size()){
cursor1++;
}
}
@Override
public void previous() {
if(cursor2 > -1){
cursor2 --;
}
}
@Override
public boolean isLast() {
return (cursor1 == products.size());
}
@Override
public boolean isFirst() {
return (cursor2 == -1);
}
@Override
public Object getNextItem() {
return products.get(cursor1);
}
@Override
public Object getPreviousItem() {
return products.get(cursor2);
}
}
(5)客户端
public class Client {
public static void main(String[] args) {
List<Object> products = new ArrayList<Object>();
products.add("倚天剑");
products.add("屠龙刀");
products.add("断肠草");
products.add("葵花宝典");
products.add("四十二章经");
AbstractObjectList list;
AbstractIterator iterator;
list = new ProductList(products);//创建聚合对象
iterator = list.createIterator();//创建迭代器对象
System.out.println("正向遍历:");
while (!iterator.isLast()){
System.out.println(iterator.getNextItem()+",");
iterator.next();
}
System.out.println();
System.out.println("--------------------");
System.out.println("逆向查询:");
while (!iterator.isFirst()){
System.out.println(iterator.getPreviousItem()+",");
iterator.previous();
}
}
}
(6)输出结果及路径
5.使用内部类实现迭代器
不管哪种实现机制,客户端代码都是一样的,这很棒
/**
* 商品数据类,充当具体聚合类
*/
public class ProductList extends AbstractObjectList {
public ProductList(List<Object> objects) {
super(objects);
}
//实现创建迭代器对象的具体工厂方法
@Override
public AbstractIterator createIterator() {
return new ProductIterator();
}
//商品迭代器:具体迭代器内部实现类
private class ProductIterator implements AbstractIterator{
private int cursor1;//定义一个游标,记录正向遍历的位置
private int cursor2;//定义一个游标,记录逆向遍历的位置
public ProductIterator(){
cursor1 = 0;
cursor2 = objects.size() - 1;
}
@Override
public void next() {
if(cursor1<objects.size()){
cursor1++;
}
}
@Override
public void previous() {
if(cursor2 > -1){
cursor2 --;
}
}
@Override
public boolean isLast() {
return (cursor1 == objects.size());
}
@Override
public boolean isFirst() {
return (cursor2 == -1);
}
@Override
public Object getNextItem() {
return objects.get(cursor1);
}
@Override
public Object getPreviousItem() {
return objects.get(cursor2);
}
}
}
6.java内置迭代器
java内置迭代器在Collection接口下。
具体使用可自行百度
7.迭代器模式优缺点
优:
(1)支持以不同的方式遍历一个聚合对象,在同一个对象上可以定义多种遍历方式
(2)简化了聚合类
(3)由于引入抽象层,增加新的聚合类和迭代器很方便
缺:
(1)增加系统复杂性
(2)设计难度大
8.迭代器使用环境
(1)访问一个聚合对象无需暴露他的内部情况
(2)需要为一个聚合对象提供多种遍历方式
(3)为遍历不同的聚合结构提供一个统一的接口,并且在该接口的实现类中为不同的聚合结构提供不同的遍历方式,而客户端可以一致性的操作该接口