6

for(Type x:collection){...}どの広く使用されているコレクション型を使用すると、反復中に安全に削除できますxか?

また、JavaDocs で注意すべき技術用語はありますか?

説明:

最初は、for-each 構文の使用についてのみ質問しましたfor(Type x:collection){...}。ただし、より完全な答えは、このスタイルを説明し、違いがある通常のイテレーターベースのループを使用することです...問題は、どの標準コレクションが反復中に要素を削除できるか、および反復を実行してこれを許可する方法です。

4

3 に答える 3

5

そのようなコレクションの 1 つがCopyOnWriteArrayList. java.util.concurrentパッケージ内の他のコレクションは、この機能を共有しています。

イテレータConcurrentModificationExceptionが a をスローしないという事実は、このクラスのコピー オン ライト セマンティクスの副作用です。変更するたびに、基になる配列がコピーされます。これは、頻繁に読み取られるがほとんど変更されないリストへの高速な同時アクセスを可能にするために行われます。

JavaDoc では、次のように説明されています (強調は私のものです)。

「スナップショット」スタイルの反復子メソッドは、反復子が作成された時点での配列の状態への参照を使用します。この配列はイテレータの有効期間中に変更されることはないため、干渉は不可能であり、イテレータは をスローしないことが保証されていますConcurrentModificationException

更新のコストが高いことに加えて、この実装にはさらにいくつかの欠点があります。

イテレータは、イテレータが作成されてからのリストへの追加、削除、または変更を反映しません。イテレータ自体 ( removeset、およびadd) に対する要素変更操作はサポートされていません。これらのメソッドは をスローしUnsupportedOperationExceptionます。

これらのコレクションは、「簡単な」ループと削除を可能にするためのユーティリティではなく、多くのスレッドが変更可能なデータへの同時アクセスを必要とする同時実行性の高い状況で使用するための特殊なコレクションであることに注意してください (ただし、通常はほとんど変更されません)。 . 単純にすべてを に置き換えないでくださいArrayListCopyOnWriteArrayList

于 2012-05-18T11:53:36.940 に答える
0

経験則として、その名前に Concurrent または Blocking が含まれるもの、別名。ConcurrentLinkedListConcurrentSkipListSetLinkedBlockingDequeLinkedBlockingQueueなど。 ConcurrentHashMap および ConcurrentSkipListMap の keySet()、values() など。ほとんどの java.util.concurrent はConcurrentModificationException良いです。

COWArrayList は、通常、サイズの小さいコレクションまたはほとんど変更されないコレクションに役立ちます...明示的なset方法は避ける必要があります。

1 つの重要な注意: iterator.remove の使用は常に Collection.remove を優先する必要があります (バグのある方法で実装されている CHM.entrySet() を除く) [使用可能な場合、COWArrayList イテレーターは削除をサポートしません]。すべての非ランダム アクセス構造は、O(n) の可能性がある要素を検索する必要がないという利点があります。

全体的ConcurrentModificationExceptionに中途半端なアイデアとその実装でした。いくつかの副作用が含まれます。ハードウェア トランザクション メモリの動作を妨げます。めったに必要とされない追加のパフォーマンス コストが発生します。HashMapひどい実装があります。揮発性の modCount を使用します (変更時に書き込まれ、反復ごとに読み取られますが、x86 では読み取りは自由です)。

于 2012-05-18T21:37:53.183 に答える
-1

おそらく少し遅い答えですが、Java 8 では、反復中にコレクションから要素を削除することがはるかに簡単になります。

removeIf(Predicate<? super E> filter)

指定された述語を満たすこのコレクションのすべての要素を削除します。

于 2016-06-15T18:46:23.153 に答える