Index
以下の書籍です。
その中から今回はItaratorパターンについて勉強したので、メモ。
この書籍の中ではItaratorパターンを以下のように説明していました。
for文でi++でiを1ずつ増加させていくと、現在注目している要素を「次」「その次」「またその次」に進めていることになります。
このようにしてiを増やして要素全体を最初から順番にスキャンしていることになります
ここで使われている変数iの動きを抽象化し、一般化したものをIteratorパターンとよぶ
Java言語によるデザインパターン
つまりよく見る以下のようなコードを抽象化してしまおうということですね。
1 2 3 |
for(int i = 0; i< array.size() ; i++){ System.out.println(array[i]); } |
1:上記の冗長なfor文のコードを以下のように簡略化できます。
1 2 3 |
for(arrayItem item : array){ System.out.println(item); } |
2:コードの再利用性が高まる
これはサンプルコードを見たのちに説明します。
サンプルコードの全容はgithubに上げましたので参照ください。(初めて公開したので失敗してら教えてください)
また今回紹介するのは本を参考に自分なりに作ってみたプログラムです(流石に丸写しはダメだと思うので)
簡単な辞書のプログラムを作ってみようと思います。
1 2 3 4 5 6 7 8 9 10 11 |
public class Word { private String word; public Word(final String word) { this.word = word; } public String getWord() { return word; } } |
文字を記録して、取得するだけの簡単なクラス
wordを格納するクラスです。
Wordを繰り返し処理したいときにiteratorメソッドが呼び出されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Dictionary implements Iterable<Word> { private List<Word> words; public Dictionary() { this.words = new ArrayList<>(); }; //indexを指定することでそこに格納されているwordを取得 public Word getDictionaryAt(int index) { return words.get(index); } //wordを追加 public void appendWord(final Word word) { words.add(word); } public int getLength() { return words.size(); } @Override public Iterator<Word> iterator() { return new DictionaryIterator(this); } } |
このクラスが肝になるクラス。
Wordを繰り返し処理したいときに呼び出されるメソッドが詰まっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import java.util.Iterator; import java.util.NoSuchElementException; public class DictionaryIterator implements Iterator<Word> { private Dictionary dictionary; private int index = 0; public DictionaryIterator(Dictionary dictionary) { this.dictionary = dictionary; } @Override public boolean hasNext() { if(index < dictionary.getLength()) { return true; } else { return false; } } @Override public Word next() { if(!hasNext()) { throw new NoSuchElementException(); } Word word = dictionary.getDictionaryAt(index); index++; return word; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Main { public static void main(String[] args) { Dictionary dictionary = new Dictionary(); dictionary.appendWord(new Word("apple")); dictionary.appendWord(new Word("lemon")); dictionary.appendWord(new Word("peach")); dictionary.appendWord(new Word("melon")); for(Word word: dictionary) { System.out.println(word.getWord()); } } } |
1 2 3 4 |
apple lemon peach melon |
こんな感じでなかなかめんどくさいし、バグが混入しやすいですね…
1 2 3 |
for(int i = 0; i < dictionary.getLength(); i++) { System.out.println(dictionary.getDictionaryAt(i).getWord()); } |
main文のfor文を見ていただければわかりますが、for文自体型を意識していないので、
たとえDictionaryクラスでList<Word>の持ち方が変わったとしても、getWord()メソッドさえ持っていれば、main文はいじらなくてすみます:)
自分で理解していても、文字に起こすのはすごく大変ですね。
何か間違っていたり、もっとこうするといいよなどあれば、教えていただきたいです!