設計模式 | 迭代器模式(iterator)

定義:

提供一種方法順序訪問一個聚合對象中各個元素,而又不暴露該對象的內部表示。

結構:(書中圖,侵刪)

一個抽象的聚合類
若干個具體的聚合類,有一個生成迭代器的方法(至關於實現java的Iterable接口)
一個抽象的迭代器,定義了迭代所必須的方法
若干個具體的迭代器
 
來學習一下java中結構
《Java編程思想》中,有關集合的類圖(應該是java5的,總體結構應該變化不大):

感受太複雜了,看起來頭疼,本身看源碼畫了一個和迭代器有關的類圖(以ArrayList爲例,java8):java

實例:

就來仿照一個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大於數組大小
鼠
牛
虎
兔
-------換成倒序-------
兔
虎
牛
鼠

總結:

本身去實現會發現不少的問題,迭代器幾乎每天都在用,實在不知道該總結些什麼。
就用書中的原話吧:
迭代器模式就是分離了集合對象的遍歷行爲,抽象出一個迭代器類來負責,這樣既能夠作到不暴露集合的內部結構,又可以讓外部代碼透明地訪問集合內部的數據。
相關文章
相關標籤/搜索