Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。

Iteratorインタフェース

このページではIteratorインタフェースの使用方法について説明します。

Iteratorインタフェースの概要

Iteratorインタフェースはコレクション内の要素に順番にアクセスする手段を提供します。コレクション・フレームワーク内のクラスは何らかの手段でこのIteratorインタフェースを使用できます。

IteratorインタフェースはEnumerationインタフェースの後継としてJ2SDK1.2以降より定義されています。下位互換性のため両方使用できますが、現在はIteratorインタフェースの使用が推奨されています。両者は以下の点で異なります。

  • Iteratorインタフェースは処理中に要素を安全に削除する仕組みを持っていますが、Enumerationインタフェースはそのような仕組みを持っていません。
  • Vectorクラス、Hashtableクラスなど古いコレクションAPIはEnumerationインタフェース、Iteratorインタフェースの両方をサポートしていますが、ArrayListクラス、HashMapクラスなど新しいコレクションAPIはIteratorインタフェースのみしかサポートしていません。

Iteratorインタフェースのメソッド

戻り型 メソッド 説明
boolean hasNext( ) 繰り返し処理において、次の要素がある場合にtrueを返します。
Object next( ) 繰り返し処理において、次の要素を返します。
void remove( ) 繰り返し処理において呼び出された、最後の要素を削除します。

Iteratorインタフェースは主に以下のようなフォーマットで実行されます。

forループを使用した場合

for (Iterator i = c.iterator(); i.hasNext();) {
    -----何らかの処理-----
    -----何らかの処理-----
    -----何らかの処理-----
}

// (1) iteratorメソッドを使用し、Iterator変数iに反復子を代入します。
// (2) hasNextメソッドを使用し、次の要素がある場合(trueを返す場合)forループ処理を続けます。 

※ cはiteratorメソッドを定義しているクラスのオブジェクトです。

whileループを使用した場合

Iterator i = c.iterator();
while (i.hasNext()) {
    -----何らかの処理-----
    -----何らかの処理-----
    -----何らかの処理-----
}

// (1) iteratorメソッドを使用し、Iterator変数iに反復子を代入します。
// (2) hasNextメソッドを使用し、次の要素がある間(trueを返す間)whileループ処理を続けます。

※ cはiteratorメソッドを定義しているクラスのオブジェクトです。

【例1】 Iteratorインタフェースを使用して、HashSet内の要素を順番に削除する例です。

import java.util.*;

public class ExCollection9 {
    public static void main(String[] args) {
        Set hs1 = new HashSet();  //(1)オブジェクト生成

        for (int i = 0; i < 10; i++) {
            hs1.add(new Integer(i));  //(2)要素の追加
        }
        System.out.println("削除前" + hs1);  //(3)要素の表示

        for (Iterator i = hs1.iterator(); i.hasNext();) {  //(4)Iterator処理
            i.next();  //(5)次の要素の呼び出し
            i.remove();  //(6)要素の削除
        }
        System.out.println("削除後" + hs1);  //(7)要素の表示
    }
}

解説1

  1. (1)HashSetクラスのオブジェクトhs1を生成します。
  2. (2)forループを使用し、0から9まで順番にオブジェクトhs1に要素を追加します。
  3. (3)オブジェクトhs1の要素を表示します。
  4. (4)Iterator処理により、hs1オブジェクトの要素の初めから最後まで順番にアクセスします。
  5. (5)nextメソッドにより、次の要素を呼び出します。
  6. (6)removeメソッドにより、最後に呼び出された(nextメソッドにより呼び出された)要素を削除します。
  7. (7)オブジェクトhs1の要素を表示します。

実行結果1

D:\JAVA>javac ExCollection9.java

D:\JAVA>java ExCollection9
削除前[2, 4, 9, 8, 6, 1, 3, 7, 5, 0]
削除後[ ]   # removeメソッドにより、要素が削除されています。

D:\JAVA>

SetのIteratorインタフェース

Setインタフェースを実装したクラス(HashSet、TreeSet、LinkedHashSet)において、Iteratorインタフェースを利用する場合は上記の概要において解説した方法と同様の方法で利用できます。

ListのIteratorインタフェース

Listインタフェースを実装したクラス(ArrayList、LinkedList)ではIteratorインタフェースに加えて、ListIteratorインタフェースを利用できます。ListIteratorインタフェースはIteratorインタフェースを機能拡張したものです。ListIteratorインタフェースは以下の点でIteratorインタフェースと異なります。

  • Iteratorインタフェースは後方への順次アクセスのみサポートしていますが、ListIteratorインタフェースは後方への順次アクセスに加えて、前方への順次アクセスもサポート(previousメソッド、hasPreviousメソッド)しています。
  • Iteratorインタフェースは削除(removeメソッド)しかサポートしていませんが、ListIteratorインタフェースは削除に加え、追加(addメソッド)、変更(setメソッド)もサポートしています。
  • ListIteratorインタフェースはList中の現在位置を知らせるメソッド(nextIndexメソッド、previousメソッド)をサポートしています。

【例2】 ListIteratorインタフェースの使用例を例示します。

import java.util.*;

public class ExCollection10 {
    public static void main(String[] args) {
        List ll1 = new LinkedList();  //(1)オブジェクトの生成

        for (int i = 0; i < 10; i++) {
            ll1.add(new Integer(i));  //(2)要素を追加
        }

        //(3)後方への順次アクセス
        for (Iterator i = ll1.iterator(); i.hasNext();) {
            System.out.println("後方処理" + i.next());
        }

        //(4)前方への順次アクセス
        for (ListIterator i = ll1.listIterator(ll1.size()); i.hasPrevious();) {
            System.out.println("前方処理" + i.previous());
        }
    }
}

解説2

  1. (1)LinkedListクラスのオブジェクトll1を生成します。
  2. (2)forループを使用し、0から9まで順番にオブジェクトll1に要素を追加します。
  3. (3)Iteratorインタフェースを使用し、オブジェクトll1の要素を前方から後方へ順次アクセスします。
  4. (3)-1iteratorメソッドを使用し、Iterator処理の反復子を変数iに代入します。
  5. (3)-2hasNextメソッドは直後に要素が存在するかチェックします。存在する場合はtrueを返します。
  6. (3)-3nextメソッドは直後の要素を返します。nextメソッドで返された要素をprintlnメソッドで表示します。
  7. (4)ListIteratorインタフェースを使用し、オブジェクトll1の要素を後方から前方へ順次アクセスします。
  8. (4)-1listIteratorメソッドを使用し、ListIterator処理の反復子を変数iに代入します。listIteratorメソッドに引数を指定した場合は、引数に指定されたインデックス番号に位置付けられた反復子を変数iに代入します。
  9. (4)-2hasPreviousメソッドは直前に要素が存在するかチェックします。存在する場合はtrueを返します。
  10. (4)-3previousメソッドは直前の要素を返します。previousメソッドで返された要素をprintlnメソッドで表示します。

実行結果2

D:\JAVA>javac ExCollection10.java

D:\JAVA>java ExCollection10
後方処理0  # 後方処理開始
後方処理1
後方処理2
後方処理3
後方処理4
後方処理5
後方処理6
後方処理7
後方処理8
後方処理9  # 後方処理終了
前方処理9  # 前方処理開始
前方処理8
前方処理7
前方処理6
前方処理5
前方処理4
前方処理3
前方処理2
前方処理1
前方処理0  # 前方処理終了

D:\JAVA>

MapのIteratorインタフェース

Mapインタフェースを実装したクラス(HashMap、TreeMap、LinkedHashMap)でIterator処理を行う場合はMapインタフェースで定義されているkeySetメソッド、valuesメソッド、entrySetメソッドを使用します。これらのメソッドは返り値としてMapオブジェクトの要素を保持したCollectionオブジェクトを返します。返されたCollectionオブジェクトからiteratorメソッドを呼び出し、Iterator処理を行います。

戻り型 メソッド 説明
Set keySet( ) 呼び出したMapオブジェクトのKeyを保持したSetを返します。
Collection values( ) 呼び出したMapオブジェクトの値を保持したCollectionを返します。
Set entrySet( ) 呼び出したMapオブジェクトのKeyと値のペアを保持したSetを返します。

【例3】Mapインタフェースを実装したクラスでのIterator処理を例示します。

import java.util.*;

public class ExCollection11 {
    public static void main(String[] args) {
        Map hm1 = new HashMap();  //(1)オブジェクトの生成
        String[] tel = {"092", "06", "052", "03", "011"};  //(2)
        String[] area = {"Fukuoka", "Osaka", "Nagoya", "Tokyo", "Hokkaido"};  //(3)

        for (int i = 0; i < 5; i++) {
            hm1.put(tel[i], area[i]);  //(4)要素の追加
        }

        Set map_ite1 = hm1.keySet();  //(5)MapのKeyを代入
        //(6)Iterator処理
        for (Iterator i = map_ite1.iterator(); i.hasNext();) {
            System.out.println("KeyのIterator:" + i.next());
        }

        Collection map_ite2 = hm1.values();  //(7)Mapの値を代入
        //(8)Iterator処理
        for (Iterator i = map_ite2.iterator(); i.hasNext();) {
            System.out.println("値のIterator:" + i.next());
        }

        Set map_ite3 = hm1.entrySet();  //(9)MapのKeyと値のペアを代入
        //(10)Iterator処理
        for (Iterator i = map_ite3.iterator(); i.hasNext();) {
            System.out.println("Keyと値のペアのIterator:" + i.next());
        }
    }
}

解説3

  1. (1)HashMapクラスのオブジェクトhm1を生成します。
  2. (2)オブジェクトhm1のKey項目に代入する配列telを生成します。
  3. (3)オブジェクトhm1の値項目に代入する配列areaを生成します。
  4. (4)forループを使用し、オブジェクトhm1に要素を追加します。
  5. (5)keySetメソッドを使用し、hm1オブジェクトのKey要素をSetインタフェース変数map_ite1に代入します。
  6. (6)Iterator処理により、hm1オブジェクトのKey要素を表示します。
  7. (7)valuesメソッドを使用し、hm1オブジェクトの値要素をCollectionインタフェース変数map_ite2に代入します。
  8. (8)Iterator処理により、hm1オブジェクトの値要素を表示します。
  9. (9)entrySetメソッドを使用し、hm1オブジェクトのKeyと値のペアをSetインタフェース変数map_ite3に代入します。
  10. (10)Iterator処理により、hm1オブジェクトのKeyと値のペアを表示します。

実行結果3

D:\JAVA>javac ExCollection11.java

D:\JAVA>java ExCollection11
KeyのIterator:03   # keySetメソッドによるIterator処理
KeyのIterator:011
KeyのIterator:052
KeyのIterator:06
KeyのIterator:092
値のIterator:Tokyo  # valuesメソッドによるIterator処理
値のIterator:Hokkaido
値のIterator:Nagoya
値のIterator:Osaka
値のIterator:Fukuoka
Keyと値のペアのIterator:03=Tokyo  # entrySetメソッドによるIterator処理
Keyと値のペアのIterator:011=Hokkaido
Keyと値のペアのIterator:052=Nagoya
Keyと値のペアのIterator:06=Osaka
Keyと値のペアのIterator:092=Fukuoka

D:\JAVA>

5Iteratorインタフェース