java - threadlocalrandom - ConcurrentModificationException para ArrayList
thread pool java (6)
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<Item> iter = list.iterator();
while(iter.hasNext()) {
Item blah = iter.next();
if(...) {
iter.remove(); // Removes the ''current'' item
}
}
Esta pregunta ya tiene una respuesta aquí:
Tengo el siguiente fragmento de código:
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();
}
Cuando intento 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?
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.
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();
}
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<DrugStrength> it = aDrugStrengthList.iterator(); it.hasNext(); ) {
DrugStrength aDrugStrength = it.next();
if (!aDrugStrength.isValidDrugDescription()) {
it.remove();
}
}
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
debería haber una implementación concurrente de la interfaz de lista que soporta dicha operación.
prueba java.util.concurrent.CopyOnWriteArrayList.class