5

現在のノードの後に​​オブジェクトを追加したり、現在のノードの後に​​オブジェクトを削除したりするときに、どのようにIteratorスローしますか。基になるコレクションへのコピーまたは参照を維持しますかConcurrentModificationException?Iterator

4

5 に答える 5

5

イテレータは、基になるコレクションへの参照を維持します。要素を追加または削除すると、イテレータが不可能なインデックスのままになるか、コレクションがイテレータの「下から」変更される可能性があります。

したがって、ほとんどのコレクションは、通知せずにイテレーターを破損させるのではなく、反復中にコレクションを変更しようとするとConcurrentModificationExceptionをスローするので、予期せず破損したイテレーターになってしまうことはありません。

于 2012-06-12T15:06:31.730 に答える
2

Iterator.remove()契約により、反復中にコレクションを変更することは許可されていません ( et alを使用する場合を除く)。

これを行うとランダムに失敗する代わりに、コレクションは変更された回数を追跡し、ConcurrentModificationException同時変更を検出するとスローするのに十分です。

于 2012-06-12T15:07:52.993 に答える
1

削除するには、次のように iterator.remove() を使用できます。

for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Object object = iterator.next();
    /* ... */
    if (condition) {
       iterator.remove();
    }

追加するために、次のように単純な Iterator を ListIterator に置き換えることができます。

ListIterator<Object> iterator = list.listIterator();
iterator.add(new Object());
于 2012-08-08T04:54:28.373 に答える
0

もちろん、イテレータには基になるコレクションへのリンクがあり、これによりコピーが回避されます。たとえば、ArrayListイテレータ(ListItr)のソースコードを見ると、ほとんどの場合、リストへのリンクとカーソルが含まれていることがわかります。

したがって、スレッド間でイテレータを共有したり、反復しているコレクションを変更したりしないでください。

于 2012-06-12T15:06:25.130 に答える