そのリストのオブジェクトとイテレータがあるList
としましょう。
今、私はリストを並べ替えますjava.util.Collections.sort()
- イテレータはどうなりますか?
- その動作はまだ定義されており、引き続き使用できますか?
- そうでない場合、リストのイテレータの破棄を防ぐことはできますか?
この問題は、プログラムの設計を変更したり、リストのクローンを作成したりすることで回避できることはわかっていますが、特にJavaの「公式」な動作を知りたいと思います。
そのリストのオブジェクトとイテレータがあるList
としましょう。
今、私はリストを並べ替えますjava.util.Collections.sort()
この問題は、プログラムの設計を変更したり、リストのクローンを作成したりすることで回避できることはわかっていますが、特にJavaの「公式」な動作を知りたいと思います。
イテレータ自体を使用する場合を除き、イテレータは通常、基になるコレクションを変更した後は無効になります。(たとえば、ListIterator
挿入と取り外しが可能です。)
ただし、並べ替え後にイテレータが無効になることは確かに予想されますが、そうでない場合は、どのような順序が予想されるかわかりません。
のコレクションのほとんどjava.util
は「フェイルファスト」であり、基になるコレクションが変更された場合に をスローする可能性があります。ConcurrentModificationException
これはデバッグ用であり、保証されていないことに注意してください。javadocs によると、これは のすべての子孫に当てはまりますAbstractList
が、マルチスレッドでの使用を意図した には当てはまりません。CopyOnWriteArrayList
一般に、コレクションのあらゆる種類の変更は、その反復子を無効にします。イテレーターを介して行われたミューテーションは、そのイテレーターを無効にしません。など、例外的なコレクションの実装がいくつかありますCopyOnWriteArrayList
。
一般的な解決策は、コレクションのコピーをソートするか、イテレータを再作成することです。
反復中にコレクションがソートされたときに何が起こるかを確認するために、いくつかのコードを作成しました。イテレータは例外をスローしないようですが、通常どおり反復を続けます。それでも、ソートされていないコレクションを反復処理することを期待している場合は、間違った結果が得られます。それを見てください :
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());
}
}
それが役に立てば幸い。