ConcurrentModificationException para ArrayList

Tengo el siguiente fragmento de código:

private String toString(List 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(); } 

Cuando bash ejecutarlo, obtengo ConcurrentModificationException , ¿alguien puede explicar por qué sucede, incluso si el código se ejecuta en el mismo hilo? ¿Y cómo podría evitarlo?

No puede eliminar de la lista si lo está navegando con el bucle “for each”. Puedes usar Iterator . Reemplazar:

 for (DrugStrength aDrugStrength : aDrugStrengthList) { if (!aDrugStrength.isValidDrugDescription()) { aDrugStrengthList.remove(aDrugStrength); } } 

Con:

 for (Iterator it = aDrugStrengthList.iterator(); it.hasNext(); ) { DrugStrength aDrugStrength = it.next(); if (!aDrugStrength.isValidDrugDescription()) { it.remove(); } } 

Al igual que las otras respuestas, no se puede eliminar un elemento de una colección sobre la que se está iterando. Puede evitar esto utilizando explícitamente un Iterator y eliminando el elemento allí.

 Iterator iter = list.iterator(); while(iter.hasNext()) { Item blah = iter.next(); if(...) { iter.remove(); // Removes the 'current' item } } 

Me gusta un orden inverso para el bucle, como:

 int size = list.size(); for (int i = size - 1; i >= 0; i--) { if(remove){ list.remove(i); } } 

porque no requiere aprender nuevas estructuras de datos o clases.

debería haber una implementación concurrente de la interfaz de lista que soporta dicha operación.

prueba java.util.concurrent.CopyOnWriteArrayList.class

Mientras itera a través del bucle, está tratando de cambiar el valor de la Lista en la operación remove (). Esto dará como resultado la ConcurrentModificationException.

Siga el siguiente código, que logrará lo que quiere y sin embargo no lanzará ninguna excepción

 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(); } 

Podemos usar clases de colección concurrentes para evitar ConcurrentModificationException al iterar sobre una colección, por ejemplo, CopyOnWriteArrayList en lugar de ArrayList.

Verifique esta publicación para ConcurrentHashMap

http://www.journaldev.com/122/hashmap-vs-concurrenthashmap-%E2%80%93-example-and-exploring-iterator