小白谈谈迭代器模式

概念

与for循环类似,用于遍历容器元素,迭代器模式提供一种方式去访问一个容器元素中的各个对象,而又不暴露该对象的内部细节。


实现

案例:今天,我们学校组织春游,当我们乘上大巴准备出发的时候,老师让我点名答到,喊名字我也懒得喊了,等下喊破喉咙今天的快乐可都没了。那我就来写个程序吧,把名字打到公交车的显示屏上,用for循环太low了,今天我们得用个高级点的技术——迭代器模式
首先我们学生是主体,那肯定有学生类:

public class Student {

    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

接下来我们来定义一个迭代器:

public interface Iterator_ {

    public abstract boolean hasNext();

    public abstract Student next();
}

我们还需要一个容器的接口:

public interface Collection_ {

    public abstract Iterator_ iterator();

    public abstract void add(Student student);
}

现在我们需要定义容器的具体实现,我们现在在公交车上,就定义公交车吧:

public class Bus implements Collection_{

    private List<Student> list;

    public Bus() {
        this.list = new ArrayList<>();
    }

    public Student getStudentAt(int index) {
        return list.get(index);
    }

    @Override
    public void add(Student student) {
        list.add(student);
    }

    public int getLength() {
        return list.size();
    }

    @Override
    public Iterator_ iterator() {
        return new BusIterator(this);
    }
}

公交车好了,得知道在公交车上怎么数人啊,所以得在公交车上实现迭代的方式:

public class BusIterator implements Iterator_ {

    //表示当前游标位置
    private int current;

    private Bus bus ;

    public BusIterator(Bus bus) {
        this.current = 0;
        this.bus = bus;
    }

    @Override
    public boolean hasNext() {
        if(current >= bus.getLength()){
            return false;
        }
        return true;
    }

    @Override
    public Student next() {
       Student student = bus.getStudentAt(current);
        current++;
        return student;
    }
}

最后就是我们的测试类了:

public class Main {
    public static void main(String[] args) {
        Collection_ bus = new Bus();
        bus.add(new Student("ctb"));
        bus.add(new Student("xiaoming"));
        bus.add(new Student("xiaohong"));
        Iterator_ iterator_ = bus.iterator();
        while (iterator_.hasNext()){
            Student student = iterator_.next();
            System.out.println(student.getName());
        }
    }
}

测试结果:
在这里插入图片描述
可能大家都察觉到了,这么简单的数数怎么不用个for循环呢,还要写这么多代码,多烧脑筋啊,所以说数组存储的数据不太需要使用迭代的方式进行遍历,如果是链表,hash表存储的数据,使用迭代的方式进行遍历,会变得简便很多:
下面给出使用链表存储的数据,通过迭代器模式进行遍历:
其中学生类,容器接口,迭代器接口同上

同样的,实现容器的具体类:

public class Bus implements Collection_ {

    //容器中的元素个数
    private int size = 0;

    //头节点
    public Node head = null;

    //尾节点
    public Node tail = null;

    @Override
    public void add(Student student){
        Node node = new Node(student);

        node.next = null;

        //添加的元素为一个元素时
        if(head == null){
            head = node;
            tail = node;
        }

        //将添加元素前的链表最后一个元素的尾节点设置为指向该元素
        tail.next = node;

        //将链表的最后一个元素设置为该元素
        tail = node;

        //长度加1
        size++;

    }

    public int getSize(){
        return size;
    }


    @Override
    public Iterator_ iterator() {
        return new BusIterator(this);
    }
}

定义一个节点类:

public class Node {

    private Student student;

    public Node next;

    public Node(Student student) {
        this.student = student;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }
}

定义迭代器的具体实现类:

public class BusIterator implements Iterator_{

    private Bus bus;

    private Node node = null;

    public BusIterator(Bus bus) {
        this.bus = bus;
        this.node = bus.head;
    }

    @Override
    public boolean hasNext() {
        if(node != null){
            return true;
        }else{
            return false;
        }
    }

    @Override
    public Student next() {
        Student student = node.getStudent();
        node = node.next;
        return student;
    }
}

最后就是测试类:

public class Main {
    public static void main(String[] args) {
        Collection_ bus = new Bus();
        bus.add(new Student("ctb"));
        bus.add(new Student("xiaoming"));
        bus.add(new Student("xiaohong"));
        Iterator_ iterator_ = bus.iterator();
        while (iterator_.hasNext()){
            Student student = iterator_.next();
            System.out.println(student.getName());
        }

    }
}

测试结果:
在这里插入图片描述
我们可以看到,测试类修改的地方不多,但是内部代码修改的量十分大,所以这种模式可以看出封装性良好。

优点:简化了遍历方式,封装性良好

缺点:对于像数组等简易容器,使用迭代器模式会变得相对繁琐


本文的代码:https://pan.baidu.com/s/1D57kMByPF2MtoVAEBxxdYw
提取码:goqk

发布了48 篇原创文章 · 获赞 0 · 访问量 652

猜你喜欢

转载自blog.csdn.net/weixin_44943485/article/details/105342134
今日推荐