Java で Iterator Pattern を実装してみた

はじめに

最近, Gof のデザインパターンをすべて記事にしようと考えている.

そんなわけで, 今日は Iterator パターン. あまりに基本すぎて, 記事にするほどではないがするが…

Iterator パターンとは

オブジェクトの集合 (データ構造, コンテナ) があるとき, その集合の内部構造はカプセル化したままで, 要素に対して順にアクセスする方法を提供する.

コンテナオブジェクトの要素を列挙する手段を独立させることによって, コンテナの内部仕様に依存しない反復子を提供することを目的とする.

言語でサポートしていることがおおい. 拡張 for 文, for-each 文などと呼ばれる.

自前で実装するよりも, 言語に頼るほうがよい.

Java

Collection フレームワークでは, 反復子が利用できる.

List<Integer> list = LinkedList<Integer>
for (int i; list) {
System.out.println (i);
}

Iterator インタフェースを実装することで, 自前のクラスにイテレータを適用できる.

Iterator interface を実装する.

Iterator interface を実装した.

import java.util.Iterator;

public class IteratorSample {
    public static void main (String args[]) {
        myList list = new myList (1, new myList (2, new myList (3, null)));

        while (list.hasNext ()) {
            list.show ();
            list = list.next ();
        } 
        list.show ();
    }
}

class myList implements Iterator {
    myList next;
    int value;

    public myList (int value, myList next) {
        this.value = value;
        this.next = next;
    }

    @Override
    public boolean hasNext () {
        return (next != null);
    }

    @Override
    public myList next () {
        return next;
    }

    @Override
    public void remove () {
        // nop
    }

    public void show () {
        System.out.println (value);
    }
}

自前で hasNext, next メソッドを用意するよりも, Iterator interface を実装したほうが, 通に思われるというメリットがある.

関数型 Iterator パターン

関数型 Iterator パターンみたいなものを考えた. というよりも List の実装.

  • while を利用するのではなくて, 再帰を利用する.
import java.util.Iterator;

public class IteratorSample2 {
    public static void main (String args[]) {
        myList list = new myList (1, new myList (2, new myList (3, null)));
        whileLoop (list);
    }

    static void whileLoop (myList list) {
        list.show ();
        if (!list.hasNext ())
            return;
        else { 
            whileLoop (list.next ());
        }
    }
}

class myList implements Iterator<myList> {
    myList next;
    int value;

    public myList (int value, myList next) {
        this.value = value;
        this.next = next;
    }

    @Override
    public boolean hasNext () {
        return (next != null);
    }

    @Override
    public myList next () {
        return next;
    }

    @Override
    public void remove () {
        // nop
    }

    public void show () {
        System.out.println (value);
    }
}

なんか, 再帰のほうがいいな.おそまつさまでした.