導入
Javaでコレクションを操作する際、皆さんは普段どのループを使っていますか?forループ、拡張for文、あるいはStream APIでしょうか。実は、これらの裏側で動いているのが「Iterator」です。Iterator.next()の仕組みを深く理解することは、単なるコードの書き方を知ること以上に、メモリ管理やコレクション操作の安全性を高めるために非常に重要です。今回は、Iteratorの基礎から、現場で役立つ安全な反復処理の極意を解説します。
基礎知識
Javaのコレクションフレームワークにおける「反復(Iteration)」とは、リストやセットなどの要素を順番に取り出す行為を指します。
Iteratorインターフェースは、その反復処理を抽象化したものです。主に以下の2つのメソッドで構成されています。
・hasNext(): 次の要素が存在するかどうかをbooleanで返します。
・next(): 次の要素を返し、カーソルを一つ進めます。
私たちが普段何気なく使っている「拡張for文(for-each)」は、コンパイル時にこのIteratorへ変換されています。つまり、Iteratorを理解することは、Javaの基本動作を理解することと同義なのです。
実装/解決策
Iteratorを直接使うべき場面は、ループ中に要素を削除したいときです。拡張for文でループ中にListのremove()を呼ぶと、「ConcurrentModificationException」が発生してプログラムが異常終了します。これを回避するには、Iteratorのremove()メソッドを使用する必要があります。
サンプルプログラム
以下のコードは、リストから特定の条件に一致する要素を安全に削除する例です。
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorExample {
public static void main(String[] args) {
List
list.add(“Java”);
list.add(“Python”);
list.add(“C++”);
// イテレータを取得
Iterator
while (iterator.hasNext()) {
// 次の要素を取得
String item = iterator.next();
// 「Python」が含まれていたら削除する
if (“Python”.equals(item)) {
// Iterator経由の削除は安全
iterator.remove();
}
}
// 結果を表示
System.out.println(“更新後のリスト: ” + list);
}
}
応用・注意点
現場でよくある失敗として、next()を1ループ内で複数回呼び出してしまうケースがあります。next()を呼ぶたびにカーソルは先に進むため、意図しないスキップやNoSuchElementExceptionが発生します。必ず「1回のループにつき1回のnext()」を徹底してください。
また、最近のモダンなJava開発では、要素の削除を伴わないのであれば「Stream API」や「Collection.removeIf()」を使用するのが推奨されます。これらは内部でIteratorを効率的に扱ってくれるため、コードの可読性が大幅に向上します。状況に応じて「素のIterator」と「高階関数」を使い分けるのが、シニアエンジニアへの第一歩です。

コメント