设计模式——迭代器模式

我尽量不打错别字,用词准确,不造成阅读障碍。

很简单的一种设计模式,因为其在数据、集合、列表等领域被广泛使用,所以已经被各大语言收入其中进行封装;

平常我们遍历一个LinkList的时候一般会用foreach遍历,那么foreach是怎么遍历的呢?其实是内部使用了迭代器模式实现的。

补充:遍历一个ArrayList的时候一般会用for循环,遍历一个LinkList的时候一般会用foreach遍历,网上有人做了实验,结果显示ArrayList这种数组列表循环用for比较合适,LinkList这种链列表用foreach比较合适,先不探究实验的合理性。

定义:一种顺序访问集合对象中各个元素却不用暴露该对象内部实现的表示。UML如下:

迭代器模式

具体代码如下:

集合抽象类

public interface Aggregate {
     Iterator CreateIterator();
}

具体集合类

public class ConcreteAggregate implements Aggregate {

    private String[] item = new String[6];

    @Override
    public Iterator CreateIterator() {
        return new ConcreteIterator(this);
    }

    public int Count() {
        return item.length;
    }

    public Object getItem(int i) {
        return item[i];
    }

    public void setItem(int i, String value) {
        item[i] = value;
    }
}

抽象迭代器

public interface Iterator {
      Object First();
      Object Next();
      boolean IsDone();
      Object CurrentItem();
}

具体迭代器类

public class ConcreteIterator implements Iterator {

    private ConcreteAggregate mConcreteAggregate;
    private int current = 0;

    public ConcreteIterator(ConcreteAggregate concreteAggregate) {
        this.mConcreteAggregate = concreteAggregate;
    }

    @Override
    public Object First() {
        return mConcreteAggregate.getItem(0);
    }

    @Override
    public Object Next() {
        current++;
        if (current < mConcreteAggregate.Count()) {
            return mConcreteAggregate.getItem(current);
        }
        return null;
    }

    @Override
    public boolean IsDone() {
        return current >= mConcreteAggregate.Count() ? true : false;
    }

    @Override
    public Object CurrentItem() {
        return mConcreteAggregate.getItem(current);
    }
}

客户端代码:

public static void main(String args[]) {
  ConcreteAggregate concreteAggregate = new ConcreteAggregate();
  concreteAggregate.setItem(0,"1");
  concreteAggregate.setItem(1,"2");
  concreteAggregate.setItem(2,"3");
  concreteAggregate.setItem(3,"4");
  concreteAggregate.setItem(4,"5");
  concreteAggregate.setItem(5,"6");

  com.study.study.IteratorDemo.Iterator i = concreteAggregate.CreateIterator();
  while (!i.IsDone()){
        System.out.println(i.CurrentItem());
        i.Next();
   }
}

运行结果:

迭代器模式_运行结果

总的来说就是:分离集合对象的迭代行为,抽象出一个迭代器来负责,既可以做到不暴露集合内部结构又可以让外部代码透明访问内部集合的数据。 而且这样迭代起来很方便,比如,在上面的代码的前提下,如果你想要反向遍历数据,你可以写一个反向的具体迭代器类,然后在客户端代码出new一个新的对象就好了。如下:

//反向迭代器类
public class ConcreteIteratorDesc implements Iterator {

    private ConcreteAggregate mConcreteAggregate;
    private int current = 0;

    public ConcreteIterator(ConcreteAggregate concreteAggregate) {
        this.mConcreteAggregate = concreteAggregate;
        current = this.mConcreteAggregate.Count() - 1;
    }

    @Override
    public Object First() {
        return mConcreteAggregate.getItem(this.mConcreteAggregate.Count() - 1);
    }

    @Override
    public Object Next() {
        current--;
        if (current > 0) {
            return mConcreteAggregate.getItem(current);
        }
        return null;
    }

    @Override
    public boolean IsDone() {
        return current < 0 ? true : false;
    }

    @Override
    public Object CurrentItem() {
        return mConcreteAggregate.getItem(current);
    }
}

这时在客户端就可以这样访问遍历了:

com.study.study.IteratorDemo.Iterator i = concreteAggregateDesc.CreateIterator();

很方便吧,日常使用中HashMap的遍历就是使用迭代器最多,如遍历键:

Iterator iter = map.keySet().iterator();
while(iter.hasNext()){
   key = (String)iter.next();
}

因为迭代器很常用,所以Java已经把它封装在语言体系中了,使用起来很方便,基本所有的集合、数组、列表等都有封装。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值