私は次のコードを持っています:
private String toString(List<DrugStrength> aDrugStrengthList) {
StringBuilder str = new StringBuilder();
for (DrugStrength aDrugStrength : aDrugStrengthList) {
if (!aDrugStrength.isValidDrugDescription()) {
aDrugStrengthList.remove(aDrugStrength);
}
}
str.append(aDrugStrengthList);
if (str.indexOf("]") != -1) {
str.insert(str.lastIndexOf("]"), "\n " );
}
return str.toString();
}
コードを実行しようとすると、ConcurrentModificationException
が返されます。コードが同じスレッドで実行されている場合でも、その理由を説明できる人はいますか?そして、どうすればそれを回避できますか?
「for each」ループでブラウズしている場合、リストから削除することはできません。 Iterator
を使用できます。交換:
for (DrugStrength aDrugStrength : aDrugStrengthList) {
if (!aDrugStrength.isValidDrugDescription()) {
aDrugStrengthList.remove(aDrugStrength);
}
}
と:
for (Iterator<DrugStrength> it = aDrugStrengthList.iterator(); it.hasNext(); ) {
DrugStrength aDrugStrength = it.next();
if (!aDrugStrength.isValidDrugDescription()) {
it.remove();
}
}
他の答えが言うように、繰り返し処理しているコレクションからアイテムを削除することはできません。これを回避するには、明示的にIterator
を使用し、そこからアイテムを削除します。
Iterator<Item> iter = list.iterator();
while(iter.hasNext()) {
Item blah = iter.next();
if(...) {
iter.remove(); // Removes the 'current' item
}
}
私は次のようなループの逆順が好きです:
int size = list.size();
for (int i = size - 1; i >= 0; i--) {
if(remove){
list.remove(i);
}
}
新しいデータ構造やクラスを学ぶ必要がないためです。
このような操作をサポートするListインターフェイスの同時実装が必要です。
java.util.concurrent.CopyOnWriteArrayList.classを試してください
ループを繰り返し処理しているときに、remove()操作でList値を変更しようとしています。これにより、ConcurrentModificationExceptionが発生します。
以下のコードに従ってください。これにより、必要なものが実現されますが、例外はスローされません。
private String toString(List aDrugStrengthList) {
StringBuilder str = new StringBuilder();
List removalList = new ArrayList();
for (DrugStrength aDrugStrength : aDrugStrengthList) {
if (!aDrugStrength.isValidDrugDescription()) {
removalList.add(aDrugStrength);
}
}
aDrugStrengthList.removeAll(removalList);
str.append(aDrugStrengthList);
if (str.indexOf("]") != -1) {
str.insert(str.lastIndexOf("]"), "\n " );
}
return str.toString();
}
同時コレクションクラスを使用して、コレクションの繰り返し処理中にConcurrentModificationExceptionを回避できます。たとえば、ArrayListではなくCopyOnWriteArrayListです。
ConcurrentHashMapについては、この投稿を確認してください
http://www.journaldev.com/122/hashmap-vs-concurrenthashmap-%E2%80%93-example-and-exploring-iterator