Iterator(イテレータ)とは

Iterator(イテレータ)は、CollectionやMapなどのデータを繰り返し処理するデザインパターンです。デザインパターンとは、オブジェクト指向言語で使われる設計パターンのことです。

イテレータの定義

イテレータは、操作するデータ型にあわせて定義します。

Iterator<データ型>

イテレータの取得

イテレータは、iterator() で取得します。ただし、イテレータが利用できるオブジェクトのみです。

データ.iterator()

Iteratorの機能

next()

現在の要素から次の位置に進めます。

Iterator.next()

hasNext()

次の要素があるかbool値で判別します。

Iterator.hasNext()

ArrayListのイテレーター

ファイル構成

./
└── cafe/
          ├── AppIterator.java
          └── Drink.java

コンソール表示

ArrayListに「Drink」クラスのデータ作成し、イテレーターでコンソール表示してみましょう。

		ArrayList<Drink> drinkList = new ArrayList<>();
		drinkList.add(new Drink("コーヒー", 350));
		drinkList.add(new Drink("紅茶", 400));
		drinkList.add(new Drink("ほうじ茶", 300));

		//イテレーター
		Iterator<Drink> iterator = drinkList.iterator();
		//次の要素があればずっと繰り返す
		while (iterator.hasNext()) {
			//イテレーターが1つ進む
			Drink drink = iterator.next();
			System.out.println(drink.name);
		}
結果
コーヒー
紅茶
ほうじ茶

ListIterator

ListIteratorは、「Iterator」よりも高機能なイテレータです。「Iterator」は片方向に処理しますが、「ListIterator」は逆方向に処理することができます。

要素の追加

イテレータに add() でデータ追加し、繰り返し表示してみます。

ListIterator<Drink> listIterator = drinkList.listIterator();
listIterator.add(new Drink("カフェモカ", 350));
while (listIterator.hasNext()) {
	Drink drink = listIterator.next();
	System.out.println(drink.name);
}

結果

データを追加しましたが、表示されません。add() でデータ追加するとイテレータがずれてしまいます。

コーヒー
紅茶
ほうじ茶

previous()

そこでデータ追加後に、previous() でイテレーターを1つ戻すことができます。

ListIterator<Drink> listIterator = drinkList.listIterator();
listIterator.add(new Drink("カフェモカ", 350));
//イテレータを1つ戻す
listIterator.previous();
while (listIterator.hasNext()) {
	Drink drink = listIterator.next();
	System.out.println(drink.name);
}

結果

今度はすべてのデータが表示されました。

カフェモカ
コーヒー
紅茶
ほうじ茶

Mapのイテレーター

Mapのイテレート処理

Mapオブジェクトはデータ構造上、 iterator() メソッドで直接処理できません。「キー」「値」どちらかを取得してイテレートする必要があります。

キーをイテレートする場合

Map.keySet().iterator();

値をイテレートする場合

Map.values().iterator();

Calendarクラス

Javaの日付処理にCalendarクラスがあります。日付処理は国によって表記が違うため、プログラムの共通ルールで日時や曜日を数値化してデータを操作します。

曜日の定数

曜日は各国ごとに名称が違うので、プログラム上では共通の数字で処理します。日曜日を「1」とする「int」型で定義されています。

定数 数値(int型) 備考
Calendar.SUNDAY 1 日曜日
Calendar.MONDAY 2 月曜日
Calendar.TUESDAY 3 火曜日
Calendar.WEDNESDAY 4 水曜日
Calendar.THURSDAY 5 木曜日
Calendar.FRIDAY 6 金曜日
Calendar.SATURDAY 7 土曜日

曜日データのイテレート

曜日のMap定義

曜日のMapデータを日本語表示で定義します。

Map<Integer, String> weekdays = new HashMap<>();
weekdays.put(Calendar.SUNDAY, "日");
weekdays.put(Calendar.MONDAY, "月");
weekdays.put(Calendar.TUESDAY, "火");
weekdays.put(Calendar.WEDNESDAY, "水");
weekdays.put(Calendar.THURSDAY, "木");
weekdays.put(Calendar.FRIDAY, "金");
weekdays.put(Calendar.SATURDAY, "土");

Mapキーのイテレート

keySet() でMapデータのキーをすべて取得して、イテレート処理します。

Iterator<Integer> weekKeyIterator = weekdays.keySet().iterator(); 
    while (weekKeyIterator.hasNext()) {
        Integer key = weekKeyIterator.next();
    System.out.println(key);
}

結果

曜日のキーが順に表示されました。Calendarの曜日の定数が、数値になっていることがわかります。

1
2
3
4
5
6
7

Map値のイテレート

values() でMapデータの値をすべて取得して、イテレート処理します。

Iterator<String> weekValueIterator = weekdays.values().iterator(); 
    while (weekValueIterator.hasNext()) {
        String weekday = weekValueIterator.next();
    System.out.println(weekday);
}

結果

曜日の値が順に表示されました。

日
月
火
水
木
金
土

演習

問題1

以下のデータをArraList型変数「scores」を定義し、イテレートで合計値を計算してみましょう。

スコア
76
81
92
56
73

問題2

以下のデータをMap型変数「cityMap」を定義し、イテレートで「キー」を繰り返しコンソール表示してみましょう。

キー
tokyo 東京
osaka 大阪
yokohama 横浜

問題3

以下のデータをMap型変数「scoreMap」を定義して、イテレートでスコアの最大値を計算してみましょう。値のデータ型は「Score」クラスとします。

キー(Integer) 値(Scoreクラス)
1 name = A, value = 67
2 name = B, value = 91
3 name = C, value = 55
4 name = D, value = 83
5 name = E, value = 74