java 设计模式 -迭代器模式

hl.wang

发布于 2019.09.07 16:26 阅读 2659 评论 0

什么是迭代器模式?

      迭代器模式是通过将聚合对象的遍历行为分离出来,抽象成迭代器类来实现的,其目的是在不暴露聚合对象的内部结构的情况下,让外部代码透明地访问聚合的内部数据。现在我们来分析其基本结构与实现方法。

 

 

 

 

 

 

迭代器模式有什么优缺点?

优点:

1、访问一个聚合对象的内容而无须暴露它的内部表示。

2、遍历任务交由迭代器完成,这简化了聚合类。

3、它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。

4、增加新的聚合类和迭代器类都很方便,无须修改原有代码。

5、封装性良好,为遍历不同的聚合结构提供一个统一的接口。

缺点 :增加了类的个数,这在一定程度上增加了系统的复杂性

 

 

 

 

 

 

如何使用迭代器模式?

 

       现在加入我们有一个Integer类型的数组和集合,我们要遍历这两个聚合对象,我们通常可以用for循环,或者for-each循环,加入我们同时有10个呢?我们需要写10个for循环,这样不仅很麻烦,而且无用代码也很多,还浪费很多时间,还会增加系统复杂度,但是如果用迭代器模式,如果这10个集合对象的遍历逻辑是一样的那么就不需要我们来写10个for循环,下面我们来看看具体要怎么实现吧。

首先我们创建一个接口

public interface Iterator<E> {
    boolean hashNext();
    E next();
    default void remove(){
        throw new UnsupportedOperationException();
    }
}

       在接口里定义上你在遍历聚合对象时所需要的方法,在这里我只简单的写了next(),hashNext().remove()方法,根据不同的需要来增加和删除方法,下面我们来看一下实现

 

public class ListIterator implements Iterator {
   List<Integer> objectList ;
   int index = 0;
public ListIterator(List<Integer> objects){
    this.objectList = objects;
}
    @Override
    public boolean hashNext() {
        if(index<objectList.size()){
            return true;
        }
        return false;
    }
    @Override
    public Object next() {
        return objectList.get(index++);
    }
}

       这是集合对象的迭代器, 创建时需要传递进来需要遍历的集合,hashNext方法判断是否有下一个,next方法得到下一个。

 

下面我们再来写一个数组的迭代器

 

public class ArrayIterator implements Iterator {
    private Integer[] arrays;
    int index = 0;
    public ArrayIterator(Integer[] arrays){
        this.arrays = arrays;
    }
    @Override
    public boolean hashNext() {
        if(index<arrays.length){
            return true;
        }
        return false;
    }
    @Override
    public Object next() {
        return arrays[index++];
    }
}

      我们发现和集合的大同小异,因为我们这里没有什么逻辑,就是一个简单的输出,下面我们来一起测试一下吧

public class Demo {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(1);
        integerList.add(2);
        integerList.add(3);
        Integer[] integers = new Integer[2];
        integers[0] = 1;
        integers[1] = 2;
        Demo demo = new Demo();
        System.out.println("==========集合中的元素===========");
        demo.print(new ListIterator(integerList));
        System.out.println("=========数组中的元素===========");
        demo.print(new ArrayIterator(integers));
    }
    private void print(Iterator iterator){
        while(iterator.hashNext()){
            System.out.println(iterator.next());
        }
    }
}

       

        用了迭代器模式我们发现遍历聚合对象的时候只需要写一个方法遍历就可以了,不然你遍历一个需要写一个for循环,有的人说,你这个不就是把for循环单独写到一个方法里了吗,但是如果你的遍历规则不一样呢,你不就需要写多个for循环,但是用了迭代器模式之后,你可以在迭代器具体实现里规定你自己的规则,并不影响遍历的使用如果你不明白,那我们下面来告诉你是什么意思。

 

 

      下面我们遍历数组的时候只需要数组中大于5的数,然后我们修改一下迭代器规则在进行遍历

public class ArrayIterator implements Iterator {
    private Integer[] arrays;
    int index = 0;
    public ArrayIterator(Integer[] arrays){
        this.arrays = arrays;
    }
    @Override
    public boolean hashNext() {
        while(index < arrays.length){
            if(arrays[index] >5){
                return true;
            }else {
                index++;
            }
        }
        return false;
    }
    @Override
    public Object next() {
        return arrays[index++];
    }
}

 

 

 下面我们在进行测试只输出数组中大于5的数据

public class Demo {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(1);
        integerList.add(2);
        integerList.add(3);
        Integer[] integers = new Integer[3];
        integers[0] = 6;
        integers[1] = 2;
        integers[2] = 7;
        Demo demo = new Demo();
        System.out.println("==========集合中的元素===========");
        demo.print(new ListIterator(integerList));
        System.out.println("=========数组中的大于5元素===========");
        demo.print(new ArrayIterator(integers));
    }
    private void print(Iterator iterator){
        while(iterator.hashNext()){
            System.out.println(iterator.next());
        }
    }
}

 

相信现在大家对迭代器模式的好处理解的更加深刻的吧。

 

 

 

 

 

 

 

 

总结

 

1、访问一个聚合对象的内容而无需暴露它的内部表示

2、支持对聚合对象的多种遍历

3、为遍历不同的聚合结构提供一个统一的接口