设计模式 | 迭代器模式(iterator)

定义:

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

结构:(书中图,侵删)

一个抽象的聚合类
若干个具体的聚合类,有一个生成迭代器的方法(相当于实现java的Iterable接口)
一个抽象的迭代器,定义了迭代所必须的方法
若干个具体的迭代器
 
来学习一下java中结构
《Java编程思想》中,有关集合的类图(应该是java5的,整体结构应该变化不大):

感觉太复杂了,看起来头疼,自己看源码画了一个和迭代器有关的类图(以ArrayList为例,java8):

实例:

就来仿照一个arraylist吧,Iterator接口就不用写了,java已经有了。
为了简化代码量,List接口还是自己写一个。
抽象List接口:
package designpattern.iterator;

import java.util.Iterator;

public interface MyList<E> extends Iterable<E> {// 为了客户端直接通过接口使用foreach方法
    void set(E e, int index);

    E get(int index);

    void remove(int index);// 数组实现,有点麻烦,就不写了

    void changeIterator(Iterator iterator);

    int getSize();

}
ArrayList实现(并不能扩展长度):
package designpattern.iterator;

import java.util.Iterator;

public class MyArrayList<E> implements MyList<E>, Iterable<E> {
    E[] data;
    private int size;
    Iterator<E> iterator;

    public MyArrayList(E[] data) {
        super();
        this.data = data;
        size = data.length;
        iterator = new MyInteratorAsc<>(this);// 默认使用正序迭代器
    }

    @Override
    public void set(E e, int index) {
        if (index < size) {
            data[index] = e;
        } else {
            System.out.println(index + "大于数组大小");
        }
    }

    @Override
    public E get(int index) {
        return data[index];
    }

    @Override
    public Iterator<E> iterator() {
        return iterator;
    }

    @Override
    public void remove(int index) {
        throw new UnsupportedOperationException("暂未实现");
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    public void changeIterator(Iterator iterator) {
        this.iterator = iterator;

    }

}
正序迭代器:
package designpattern.iterator;

import java.util.Iterator;

public class MyInteratorAsc<E> implements Iterator<E> {
    MyList<E> myList;

    public MyInteratorAsc(MyList<E> myList) {
        super();
        this.myList = myList;
        this.current = 0;
    }

    int current;

    @Override
    public boolean hasNext() {
        if (current < myList.getSize()) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public E next() {
        return myList.get(current++);
    }

}
倒序迭代器:
package designpattern.iterator;

import java.util.Iterator;

public class MyInteratorDesc<E> implements Iterator<E> {
    MyList<E> myList;

    public MyInteratorDesc(MyList<E> myList) {
        super();
        this.myList = myList;
        this.current = myList.getSize() - 1;
    }

    int current;

    @Override
    public boolean hasNext() {
        if (current >= 0) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public E next() {
        return myList.get(current--);
    }
}
客户端:
package designpattern.iterator;

public class Client {
    public static void main(String[] args) {
        MyList<String> myList = new MyArrayList<>(new String[4]);
        myList.set("", 0);
        myList.set("", 1);
        myList.set("", 2);
        myList.set("", 3);
        myList.set("", 4);

        for (String string : myList) {
            System.out.println(string);
        }

        System.out.println("-------换成倒序-------");

        myList.changeIterator(new MyInteratorDesc<>(myList));
        for (String string : myList) {
            System.out.println(string);
        }
    }
}
结果输出:
4大于数组大小
鼠
牛
虎
兔
-------换成倒序-------
兔
虎
牛
鼠

总结:

自己去实现会发现很多的问题,迭代器几乎天天都在用,实在不知道该总结些什么。
就用书中的原话吧:
迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
posted @ 2019-06-04 20:07  莫愆  阅读(269)  评论(0编辑  收藏  举报