11

そのリストのオブジェクトイテレータがあるListとしましょう。

今、私はリストを並べ替えますjava.util.Collections.sort()

  • イテレータはどうなりますか?
  • その動作はまだ定義されており、引き続き使用できますか?
  • そうでない場合、リストのイテレータの破棄を防ぐことはできますか?

この問題は、プログラムの設計を変更したり、リストのクローンを作成したりすることで回避できることはわかっていますが、特にJavaの「公式」な動作を知りたいと思います。

4

4 に答える 4

18

イテレータ自体を使用する場合を除き、イテレータは通常、基になるコレクションを変更した後は無効になります。(たとえば、ListIterator挿入と取り外しが可能です。)

ただし、並べ替え後にイテレータが無効になることは確かに予想されますが、そうでない場合は、どのような順序が予想されるかわかりません。

于 2008-11-18T15:51:52.053 に答える
16

のコレクションのほとんどjava.utilは「フェイルファスト」であり、基になるコレクションが変更された場合に をスローする可能性があります。ConcurrentModificationExceptionこれはデバッグ用であり、保証されていないことに注意してください。javadocs によると、これは のすべての子孫に当てはまりますAbstractListが、マルチスレッドでの使用を意図した には当てはまりません。CopyOnWriteArrayList

于 2008-11-18T15:55:14.463 に答える
4

一般に、コレクションのあらゆる種類の変更は、その反復子を無効にします。イテレーターを介して行われたミューテーションは、そのイテレーターを無効にしません。など、例外的なコレクションの実装がいくつかありますCopyOnWriteArrayList

一般的な解決策は、コレクションのコピーをソートするか、イテレータを再作成することです。

于 2008-11-18T15:55:10.080 に答える
2

反復中にコレクションがソートされたときに何が起こるかを確認するために、いくつかのコードを作成しました。イテレータは例外をスローしないようですが、通常どおり反復を続けます。それでも、ソートされていないコレクションを反復処理することを期待している場合は、間違った結果が得られます。それを見てください :

public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    list.add("D");
    list.add("B");
    list.add("A");
    list.add("C");
    list.add("E");

    Iterator<String> it = list.iterator();
    String s = it.next();
    System.out.println(s);
    s = it.next();
    System.out.println(s);

    Collections.sort(list);
    Iterator<String> it2 = list.iterator();

    s = it.next();
    System.out.println(s);
    s = it.next();
    System.out.println(s);
    s = it.next();
    System.out.println(s);

    while (it2.hasNext()) {
        System.out.println(it2.next());
    }
    }

それが役に立てば幸い。

于 2008-11-18T16:13:14.617 に答える