第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); } }
結果が正常に表示されましたね。