秒懂设计模式之迭代器模式(Iterator Pattern)

Posted ShuSheng007

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了秒懂设计模式之迭代器模式(Iterator Pattern)相关的知识,希望对你有一定的参考价值。

[版权申明] 非商业目的注明出处可自由转载
博文地址:https://blog.csdn.net/ShuSheng0007/article/details/117903838
出自:shusheng007

设计模式汇总篇,一定要收藏:

永不磨灭的设计模式(有这一篇真够了,拒绝标题党)

在这里插入图片描述

概述

迭代器模式如此常用,以至于很多编程语言都默认实现了此模式,所以虽然我们天天都在用迭代器模式,但却很少有自己实现的机会。

其核心动机是为了在迭代一个容器对象的同时不暴露其内部细节,这啥意思呢?

例如ArrayList类,当我们需要迭代它的元素的时候,我们不可能将其内部存储元素用的数据结构,例如数组,暴露给用户。那样的话不仅将来更换数据结构变的不可能,而且如果将内部细节暴露给了客户端,那么就无法控制客户端对其行为了。

类型

行为型(behavioral)

难度

2颗星

定义

提供一种方法顺序访问一个容器对象中的各个元素,而又不需要暴露该对象的内部表示。

使用场景

在java开发中,当你要你要实现自己的容器类,且要迭代里面的元素时。换句话还可以说,当你要使自己的类支持foreach 操作的时候使用此模式。

在Java中没有必要自己实现这个模式,因为Java类库默认支持了此模式,所以此处我们也以Java官方类库为例谈论一下,因为我想写一些有用的东西,而不是华而不实的东西。

实例

在我们上大学的时候,无论哪一科的老师都喜欢在课前点名,为什么会这样呢?是因为老师不知道自己班级有几名学生吗?当然不是,恰恰是因为老师明知道自己班级有多少学生,但放眼望去到场的却寥寥无几… 毕业多年,现在想想真的很怀念自己的大学生活,只恨当年为什么不拼命学习,拼命做一些有意义的事,我们的青春啊…

老师点名肯定是从头点到尾,对班里的每一个学生进行迭代…

相应接口

由于Java已经天然支持了迭代器模式,我们直接使用就好了。主要涉及如下两个接口,看起来好简单对不对?对啊,本来也没多难。不过大概10年前吧,我第一次从C#中看到这两类似的玩意还是没有理解了。哎, 又应了那句老话:在老鸟眼里的土坷垃就是菜鸟眼前的一座大山啊!

public interface Iterator<E> {
    boolean hasNext();
    E next();

   //java8后加入的default方法
    ...
}
public interface Iterable<T> {
    Iterator<T> iterator();
    
   //java8后加入的default方法
    ...    
}

如果我们要使自己的类支持迭代功能,只需要实现Iterable 接口,而这个接口仅仅是要求实现一个方法,提供一个迭代器。而这个迭代器要实现Iterator接口,所以我们唯一需要做的就是提供一个实现了Iterator接口的类而已。

实现

如下所示,我写了一个Class类,它实现了Iterable 接口。然后内部类Itr作为迭代器。此类中我使用ArrayList 作为内部数据结构,后期也可以换成数组,链表,树,图等等,而使用者却不用关心这些内部表示,这就是迭代器的妙处所在。

public class Class implements Iterable<Student> {
    private final List<Student> students = new ArrayList<>();

    public Class() {
        students.add(new Student("王二狗", 28));
        students.add(new Student("牛翠花", 20));
        students.add(new Student("林蛋大", 29));
    }

    public boolean addStudent(Student student){
       return students.add(student);
    }

    public boolean removeStudent(Student student){
       return students.remove(student);
    }

    @Override
    public Iterator<Student> iterator() {
        return new Itr();
    }

    private class Itr implements Iterator<Student> {

        int index = 0;

        @Override
        public boolean hasNext() {
            if (index < students.size()) {
                return true;
            }
            return false;
        }

        @Override
        public Student next() {
            Student student = students.get(index);
            index++;
            return student;
        }
    }
}

客户端使用

相信有过点Java编程经验的用起这个类时都非常得心应手,因为他不知道已经用了多少次了。获取Class对象的迭代器,然后使用while循环迭代即可。

public class IteratorClient {

    public void checkAttendance(){
        Class cls= new Class();
        System.out.println("--------------开始点名--------------");
        Iterator<Student> iterator= cls.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

输出:

--------------开始点名--------------
Student{name='王二狗', age=28}
Student{name='牛翠花', age=20}
Student{name='林蛋大', age=29}

值得注意的是,我们也可以对Class类使用foreach循环

 for (Student cl : cls) {
     System.out.println(cl);
 }

技术要点总结

你要使你的类可以迭代(支持foreach),就实现java.lang.Iterable接口。

总结

设计模式值得你可以练习!

祝广大程序员同行,端午节快乐,祝愿我们的生活越来越好…

GitHub源码地址design-patterns

以上是关于秒懂设计模式之迭代器模式(Iterator Pattern)的主要内容,如果未能解决你的问题,请参考以下文章

JAVA设计模式之迭代器设计模式

设计模式之迭代器模式 Iterator

23种设计模式之迭代器模式(Iterator)

25行为型模式之迭代器模式

行为模式之迭代器模式

设计模式之三:迭代器模式(IteratorPattern)