Javaのイテレータガイド

Javaのイテレータのガイド

1. 前書き

Iteratorは、コレクションをトラバースできる多くの方法の1つであり、すべてのオプションとして、長所と短所があります。

これは、Enumerationsの代わりとしてJava1.2で最初に導入されました。

このチュートリアルでは、単純なIteratorインターフェースを確認して、さまざまなメソッドの使用方法を学習します。

また、いくつかの興味深い機能を追加する、より堅牢なListIterator拡張機能も確認します。

2. Iteratorインターフェース

まず、CollectionからIteratorを取得する必要があります。これは、iterator()メソッドを呼び出すことによって行われます。

簡単にするために、リストからIteratorインスタンスを取得します。

List items = ...
Iterator iter = items.iterator();

Iteratorインターフェースには、次の3つのコアメソッドがあります。

2.1. hasNext()

hasNext()メソッドは、反復する要素が少なくとも1つ残っているかどうかを確認するために使用できます。

whileループの条件として使用するように設計されています。

while (iter.hasNext()) {
    // ...
}

2.2. next()

next()メソッドは、次の要素をステップオーバーして取得するために使用できます。

String next = iter.next();

next()を呼び出す前に、hasNext()を使用することをお勧めします。

CollectionsIteratorsは、特定の順序での反復を保証しませんunless particular implementation provides it.

2.3. remove()

最後に、remove the current element from the collection,が必要な場合は、remove:を使用できます。

iter.remove();

これは、ConcurrentModificationException.のリスクなしに、コレクションを反復処理しながら要素を削除する安全な方法です。

2.4. 完全なIteratorの例

これらすべてを組み合わせて、コレクションフィルタリングで3つのメソッドをどのように使用するかを見てみましょう。

while (iter.hasNext()) {
    String next = iter.next();
    System.out.println(next);

    if( "TWO".equals(next)) {
        iter.remove();
    }
}

これは、別の要素があるかどうかを事前にチェックするIterator,を一般的に使用する方法であり、それを取得してから、何らかのアクションを実行します。

2.5. ラムダ式で反復する

前の例で見たように、すべての要素を調べて何かを実行したい場合は、Iteratorを使用するのは非常に冗長です。

Java 8以降、ラムダを使用して残りの要素を処理できるforEachRemainingメソッドがあります。

iter.forEachRemaining(System.out::println);

3. ListIteratorインターフェース

ListIteratorは、リストを反復処理するための新しい機能を追加する拡張機能です。

ListIterator listIterator = items.listIterator(items.size());

この場合はList.の終わりである開始位置を提供する方法に注意してください。

3.1. hasPrevious()およびprevious()

ListIteratorは後方トラバーサルに使用できるため、hasNext()およびnext()と同等のものを提供します。

while(listIterator.hasPrevious()) {
    String previous = listIterator.previous();
}

3.2. nextIndex()およびpreviousIndex()

さらに、実際の要素ではなく、インデックスを走査できます。

String nextWithIndex = items.get(listIterator.nextIndex());
String previousWithIndex = items.get(listIterator.previousIndex());

これは、現在変更しているオブジェクトのインデックスを知る必要がある場合、または削除された要素の記録を保持したい場合に非常に役立ちます。

3.3. add()

addメソッド。名前が示すように、要素before the item that would be returned by next() and after the one returned by previous():を追加できます。

listIterator.add("FOUR");

3.4. set()

言及する価値のある最後のメソッドはset(),です。これにより、next()またはprevious()の呼び出しで返された要素を置き換えることができます。

String next = listIterator.next();
if( "ONE".equals(next)) {
    listIterator.set("SWAPPED");
}

this can only be executed if no prior calls to add() or remove() were made.に注意することが重要です

3.5. 完全なListIteratorの例

すべてを組み合わせて完全な例を作成できます。

ListIterator listIterator = items.listIterator();
while(listIterator.hasNext()) {
    String nextWithIndex = items.get(listIterator.nextIndex());
    String next = listIterator.next();
    if("REPLACE ME".equals(next)) {
        listIterator.set("REPLACED");
    }
}
listIterator.add("NEW");
while(listIterator.hasPrevious()) {
    String previousWithIndex
     = items.get(listIterator.previousIndex());
    String previous = listIterator.previous();
    System.out.println(previous);
}

この例では、ListからListIteratorを取得することから始め、次にインデックス–which doesn’t increase the iterator’s internal current element –またはnextを呼び出すことによって次の要素を取得できます。

次に、特定のアイテムをsetで置き換え、新しいアイテムをadd.で挿入できます。

反復の最後に到達したら、後方に移動して追加の要素を変更するか、単に下から上に印刷します。

4. 結論

Iteratorインターフェースを使用すると、コレクションをトラバースしながらコレクションを変更できます。これは、単純なfor / whileステートメントではより困難です。 これにより、良好な凝集性と低結合を維持しながらコレクション処理のみを必要とする多くの方法で使用できる優れたパターンが得られます。

最後に、いつものように完全なソースコードはover at GitHubで利用できます。