38

「 ArrayList でイテレータを使用する必要はありますか? 」という質問に対する回答を読んでいました。

回答の中で、ユーザーは次のように述べています。

これは、Java で ArrayList の remove メソッドを使用しても実現できます。私の質問は、なぜ ArrayList にイテレータが必要なのですか?

次のコードを検討してください。

import java.util.*;
public class ocajp66 {
    public static void main(String[] args) {
        ArrayList a = new ArrayList();
        for (int i = 0; i < 10; i++) {
            a.add(i);
        }
        System.out.printf("BEFORE ITERATOR\n");
        for (int i = 0; i < a.size(); i++) {
            System.out.printf("I:%d\n", a.get(i));
        }
        System.out.printf("AFTER ITERATOR\n");
        Iterator i = a.iterator();
        while (i.hasNext()) {
            System.out.printf("I:%d\n", i.next());
        }
    }
}

イテレータの意味を説明できる人はいますか? コードで説明していただければ幸いです。

4

5 に答える 5

58

あなたが述べたように、イテレータは、配列の内容を繰り返し処理しながらものを削除したいときに使用されます。イテレータを使用せず、単純に for ループを使用し、その中で remove メソッドを使用すると、反復中に配列の内容が変更されるため、例外が発生します。例: for ループの開始時に配列サイズが 10 であると考えるかもしれませんが、要素を削除するとそうはなりません.. したがって、最後のループに到達すると、おそらく IndexOutofBoundsException などが発生します。

于 2013-04-14T14:56:18.053 に答える
1

Q: なぜ ArrayList にイテレータが必要なのですか?

コードで示したように、反復子なしで ArrayList を反復してコア操作を実行できます。でも機能があるのはいいですね。

Q: イテレータの意味を説明できる人はいますか?

その設計上の価値に加えて、私が見ることができたのは、そのフェイルファスト機能です。ArrayListのドキュメントからこの段落を引用します。

このクラスの iterator および listIterator メソッドによって返される反復子は、フェイルファストです。反復子の作成後に、反復子自体の remove メソッドまたは add メソッド以外の方法でリストが構造的に変更された場合、反復子は ConcurrentModificationException をスローします。したがって、同時変更に直面した場合、反復子は、将来の不確定な時点で恣意的で非決定論的な動作を危険にさらすのではなく、迅速かつ明確に失敗します。

コードを探していましたが、実際には ArrayList の反復子の実装を ArrayList.java で確認できます

于 2013-04-14T15:17:21.377 に答える
0

あなたの質問に対して、list.remove()代わりにメソッドを使用すると、 iterator.remove()thenIndexOutOfBoundsExceptionがスローされます。

list.remove()break削除する特定のオブジェクト/インデックスを見つけたら、例外なしでループから終了するようにステートメントを配置すると安全に使用できます(のようにIndexOutOfBoundsException)

同期環境でイテレータ EVEN を使用すると、次のイテレータ コードでもスローできます。 ConcurrentModificationException

List<String> empNames = new ArrayList<String>();
        synchronized (empNames) {
            Iterator<String> iterator = empNames.iterator();
            while (iterator.hasNext()) {
                iterator.next();
                empNames.add("Another Name"); // throws
                // ConcurrentModificationException
            }
        }
于 2013-04-14T15:35:17.707 に答える