Javaのイテレータ(拡張for構文)


要素の集まりに対する繰り返し処理をイテレーションといい、この繰り返しを抽象化したオブジェクトを「イテレータ(iterator)」と呼びます。

😎 イテレータの役割

イテレータに必要な操作を定義したIterator(java.util.Iterator)インターフェスには次の3つのメソッドがあります。

メソッド 説明
boolean hasNext() 次の要素があるかどうかを調べる
E next() まだ取り出していない、次の要素を取り出す
void remove() nextで取り出した要素を削除する

👽 サンプルソース

拡張for構文

拡張for構文を使うサンプルはこちら。

List<integer> list = new ListArray<>;
// list.add ... (リストに要素が追加されていると仮定)
int sum = 0;
// 拡張for構文
for (integer n: list) {
sum += n;
}

イテレータ

イテレータを使う場合はのサンプルはこちら。

List<integer> list = new ListArray<>;
// list.add ... (リストに要素が追加されていると仮定)
int sum = 0;
// イテレータを使うパターン
for (Iterator<integer> it = list.iterator(); it.hasNext();) {
Integer n = it.next();
sum += n;
}

イテレータの処理は順序を持たないセット(Set)に対しても行えます。

コレクションに対するイテレーション

Collectionインターフェスで受け入れるメソッドを定義すればListもSetも受け入れることができます。

// 引数に List, Set を受け入れる事ができる
int getSum(Collection<Integer> collection) {
int sum = 0;
for(integer n: collection) {
sum += n;
}
return sum;
}

マップに対するイテレーション

マップはキーとバリューの組み合わせのため、次のように記述します。

// Map<String, String> mapに要素が追加されていると仮定
// キーに対する繰り返し処理
for (String key : map.keySet()) {
system.out.println(key);
}
// 値に対する繰り返し処理
for (Iterator<String> it = map.values().iterator(); it.hasNext();) {
String val = it.next();
System.out.println(val);
}
// キーと値に対する繰り返し処理
for (Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();it.hasNext();) {
Map.Entry<String,String> entry = it.next();
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}

順序のあるリストを逆順に取得するイテレータ

// List<integer> list に要素があることを仮定
for (ListIterator<Integer> it = list.listIterator(list.size())); it.hasPrevious();) {
Integer i = it.previous();
System.out.println(i);
}

🚜 注意点

  • ループ中はコレクションの要素の追加、削除はバグを招く。ループを抜けて一気に追加、削除を行う(一時的なコレクションを作る)
  • for文の中の初期化文で変数を宣言する場合、「変数が同じ型」が必要

😀 参考リンク

📚 おすすめの書籍

🖥 サーバについて

このブログでは「Cloud Garage」さんのDev Assist Program(開発者向けインスタンス無償提供制度)でお借りしたサーバで技術検証しています。 Dev Assist Programは、開発者や開発コミュニティ、スタートアップ企業の方が1GBメモリのインスタンス3台を1年間無料で借りれる心強い制度です!(有償でも1,480円/月と格安)