设计模式之迭代器模式

什么是迭代器模式

用迭代器来封装集合对象的遍历细节,使调用者能够通过统一的接口来实现对集合的遍历。

迭代器也给集合对象提供了一定的保护,想要遍历集合,直接调用迭代器的方法就好了,我们不知道也不必知道集合内部的数据管理方式。

举个例子

有这样的一个需求。一家集团公司在北京和上海分别有一家子公司,每家公司内部有自己的部门,且自己提供了打印部门的方法。其中一个子公司以数组来保存部门列表,另外一个以ArrayList来保存。现在需要打印所有的部门。

原始实现

部门对象:

//部门对象
public class Dept {
    private String name;

    public Dept(String name){
        this.name= name;
    }

    public String getName(){
        return this.name;
    }
}
//北京分公司
public class BJBranch {
    ArrayList<Dept> depts;

    public BJBranch(){
        depts = new ArrayList<Dept>();
        //添加部门
        depts.add(new Dept("北京-财务部"));
        depts.add(new Dept("北京-研发部"));
        depts.add(new Dept("北京-开发部"));
    }

    public ArrayList<Dept> getDepts(){
        return depts;
    }
}
//上海分公司
public class SHBranch {
    Dept[] depts;

    public SHBranch(){
        depts = new Dept[3];
        //添加部门
        depts[0] = new Dept("上海-财务部");
        depts[1] = new Dept("上海-研发部");
        depts[2] = new Dept("上海-开发部");
    }

    public Dept[] getDepts(){
        return depts;
    }
}

测试代码

public class TestOld {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        BJBranch BJ             = new BJBranch();
        ArrayList<Dept> BJDepts = BJ.getDepts();
        SHBranch SH     = new SHBranch();
        Dept[] SHDepts  = SH.getDepts();
        //遍历两家子公司的所有部门
        /** 由于类型不同,需要两次循环 **/
        for(int i=0;i<BJDepts.size();i++){
            System.out.println(BJDepts.get(i).getName());
        }
        for(int i=0;i<SHDepts.length;i++){
            System.out.println(SHDepts[0].getName());
        }
    }
}

从上面的代码中可以看出,由于两家子公司的实现方式不一样,造成循环遍历时自能使用对应的方式来遍历,造成相当大的不便。

改造,使用迭代器模式

//迭代器接口
public interface Iterator {
    boolean hasNext();
    Object next();
}
//北京分公司的部门迭代器
public class BJBranchIterator implements Iterator{
    ArrayList<Dept> depts;
    int position    = 0;
    public BJBranchIterator(ArrayList<Dept> depts){
        this.depts = depts;
    }
    @Override
    public boolean hasNext() {
        if(position>=depts.size() || depts.get(position)==null){
            return false;
        }else{
            return true;
        }
    }

    @Override
    public Object next() {
        Dept dept = depts.get(position);
        position  = position + 1;
        return dept;
    }

}
//改造后的北京分公司
public class BJBranch {
    ArrayList<Dept> depts;

    public BJBranch(){
        depts = new ArrayList<Dept>();
        //添加部门
        depts.add(new Dept("北京-财务部"));
        depts.add(new Dept("北京-研发部"));
        depts.add(new Dept("北京-开发部"));
    }

    /*public ArrayList<Dept> getDepts(){
        return depts;
    }*/

    //改造为返回Iterator对象,而不是ArrayList
    public Iterator createrIterator(){
        return new BJBranchIterator(depts);
    }
}
//上海分公司的部门迭代器
public class SHBranchIterator implements Iterator{
    Dept[] depts;
    int position    = 0;
    public SHBranchIterator(Dept[] depts){
        this.depts = depts;
    }
    @Override
    public boolean hasNext() {
        if(position>=depts.length|| depts[position]==null){
            return false;
        }else{
            return true;
        }
    }

    @Override
    public Object next() {
        Dept dept = depts[position];
        position  = position + 1;
        return dept;
    }

}
//改造后的上海分公司
public class SHBranch {
    Dept[] depts;

    public SHBranch(){
        depts = new Dept[3];
        //添加部门
        depts[0] = new Dept("上海-财务部");
        depts[1] = new Dept("上海-研发部");
        depts[2] = new Dept("上海-开发部");
    }

    /*public Dept[] getDepts(){
        return depts;
    }*/

    //改造为返回Iterator对象,而不是数组
    public Iterator createrIterator(){
        return new SHBranchIterator(depts);
    }
}
//使用迭代器模式后的代码实现
public class TestNew {

    public static void main(String[] args) {
        Iterator BJ = new BJBranch().createrIterator();
        Iterator SH = new SHBranch().createrIterator();

        printDeptName(BJ);
        printDeptName(SH);
    }

    private static void printDeptName(Iterator iterator){
        while(iterator.hasNext()){
            Dept dept = (Dept) iterator.next();
            System.out.println(dept.getName());
        }
    }
}

从改造后的代码中可以看出,使用迭代器模式改造后,成功的屏蔽了北京与上海分公司遍历的差异。

至此,我们就手写了一个简单的迭代器模式。

总结

由于迭代器的方便性与必要性,Java1.5之后就提供了对Iterator的支持,目前很多集合对象都支持Iterator,例如Set, List, Map, SortedSet, SortedMap, HashSet, TreeSet, ArrayList, LinkedList, Vector等等。

唯一不支持迭代器的可能就是数组吧(栈,队列这些特殊的除外)。

Java.util.Iterator接口定义了三个方法(除hasNextnext方法外还有remove方法);

迭代器的隐式调用

很多语言都支持for each(或者 for in)循环,其内部实现就是调用了迭代器完成遍历。当然,只是一个小常识,更重要的是学会迭代器的设计原理,在需要的时候定义自己的迭代器。

扩展

迭代器模式本身比较简单,甚至我们已经不需要去定义自己的迭代器了(API提供提供的迭代器接口几乎可以满足我们的需要了)。

但迭代器与组合模式结合起来,可以做一些不可思议的事情。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值