threads threadlocalrandom thread example clase java collections concurrency

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 } }

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



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

prueba java.util.concurrent.CopyOnWriteArrayList.class