0

LinkedHashMapの同期機能に関する1つの特定の点に混乱しています。これが私が混乱している関連するJavadocです。私の混乱のポイントは、なぜここでremoveメソッドが特別なのかということです。これは、「イテレータ自体のremoveメソッドを除いて」で言及されています。

http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html

このクラスのすべてのコレクションビューメソッドによって返されるコレクションのイテレーターメソッドによって返されるイテレーターはフェイルファストです。イテレーターが作成された後、イテレーター自体のremoveメソッド以外の方法でマップが構造的に変更された場合、イテレータはConcurrentModificationExceptionをスローします。したがって、同時変更に直面した場合、イテレータは、将来の不確定な時点で任意の非決定的な動作のリスクを冒すのではなく、迅速かつクリーンに失敗します。

よろしくお願いします、リン

4

3 に答える 3

4

基本的に、マップを反復処理しているときにマップを構造的に変更することは許可されていません。これを行うと、イテレータが無効になるためです。

Iterator.remove()次のようなコードを簡単に記述できるようにするために、これは特に免除されます。

Iterator<E> it = coll.iterator();
while (it.hasNext()) {
  E val = it.next();
  if (some_condition) {
    it.remove();
  }
}
于 2013-02-03T13:57:17.940 に答える
2

これは特別なことではありません。イテレータを使用するときにコレクションからアイテムを削除する通常の方法です。要素がイテレータの「外部」で削除されると、イテレータには要素が削除された理由や方法を知る方法がないため、特定のコレクションのイテレータビューは実際のコレクションと比較して一貫性がなくなります。

イテレータにはさまざまなタイプがあります。コレクションの特定の状態を「操作」するイテレーターがあります。その場合、イテレーターの外部でコレクションを変更しても違いはありません。これは不変のコレクションでは一般的です。もう1つのタイプのイテレータは、イテレータがコレクションの古い状態を調べている(つまり、コレクションが外部から変更されている)ことがわかるとすぐに例外をスローする「フェイルファスト」イテレータです。ドキュメントに記載されているようにLinkedHashMap、フェイルファストイテレータを使用します。

于 2013-02-03T13:57:57.137 に答える
1

これは特別なことではありません。メソッドLinkedHashMapを介して要素を削除できるように、一種のロックを取得します。remove

これは、前に指定したように、次の理由によるものです。

構造変更とは、1つ以上のマッピングを追加または削除する操作、またはアクセス順序付きのリンクされたハッシュマップの場合は、反復順序に影響を与える操作です。

これは、データ構造に保留中のイテレーターがあることを意味します。変更を許可すると、決定論的動作に関して問題が発生します(基になる構造が変更されるとイテレーターの一貫性が失われるため)。したがって、実装では、開いているイテレータがある場合、メソッドを呼び出すとすぐに、例外を除いて構造的な変更が失敗します。

于 2013-02-03T13:58:18.833 に答える