株式会社イーヴ

EeBlog(テクニカルブログ)

TOP > EeBlog > 第37回 拡張for文とIterator

第37回 拡張for文とIterator

今回のテーマは「拡張for文とIterator」です。

Java5で導入された拡張for文を使うと、コレクションの走査が非常に簡単になります。 拡張for文の内部ではIteratorが使われていて、処理の内容自体はこれまでのIteratorを利用したループと変わりません。 では、拡張for文があればIteratorはもう使う必要がないのでしょうか。

実は拡張for文ではできない処理があり、Iteratorはまだまだ現役なのです。 以下のサンプルで、拡張for文ではできない処理を検証してみましょう。

import java.util.ArrayList; 
import java.util.Collection;

public class Main { 
    public static void main(String[] args) { 
        Collection<Integer> sampleCollection = new ArrayList<Integer>(); 
        for (int i = 0; i < 10; i++) { 
            sampleCollection.add(i); 
        } 
        System.out.println(sampleCollection);

        for (Integer integer : sampleCollection) { 
            if (integer % 3 == 0) { 
                sampleCollection.remove(integer); 
            } 
        } 
        System.out.println(sampleCollection); 
    } 
}

ソースを眺めて見る限りでは、そんなに不自然なところは見当たらないかもしれません。 しかし、実行してみるとjava.util.ConcurrentModificationExceptionが発生します。 イテレーション中にコレクションの要素を削除するには、Iteratorのremoveメソッドのみが唯一の安全な方法なのです。

 

では、Iteratorを使用するようにサンプルを変更してみます。

import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Iterator;

public class Main { 
    public static void main(String[] args) { 
        Collection<Integer> sampleCollection = new ArrayList<Integer>(); 
        for (int i = 0; i < 10; i++) { 
            sampleCollection.add(i); 
        } 
        System.out.println(sampleCollection);

        for (Iterator<Integer> iterator = sampleCollection.iterator(); iterator.hasNext();) { 
            if (iterator.next() % 3 == 0) { 
                iterator.remove(); 
            } 
        } 
        System.out.println(sampleCollection); 
    } 
}

結果が正常に表示されましたね。