La respuesta 4 es técnicamente correcta, pero no porque se utiliza un bucle for(;;)
o "para cada" en lugar de un bucle while()
. Simplemente es una cuestión del alcance declarado por el iterador dentro de la Clase en lugar del método. En primer lugar, vamos a ver el comportamiento de los dos métodos hasNext()
y next()
:
El método hasNext()
simplemente un cursor consultas interna (índice); next()
realmente avanza el cursor, por lo tanto esa es la "modificación" que podría generar la excepción. Si intenta utilizar un iterador declarado y asignado fuera del método en el que se usa next()
, el código emitirá una excepción en el primer next()
, independientemente de si es un for(;;)
o while()
.
En la respuesta 4 y 8, el iterador se declara y se consume localmente dentro del método. Sucede que dado que el constructo for(;;)
permite una primera declaración y asignación de tiempo del iterador antes de que se ejecute el bucle (lo que hace que el iterador alcance el for(;;)
e implícitamente dentro del método, lo que lo hace "seguro"). Estoy de acuerdo en que la expresión for(;;)
es más clara sintácticamente y delimita el alcance en el nivel más bajo de ejecución, completamente dentro del ciclo for(;;)
.
La respuesta 8 es correcta, porque el iterador se asigna y utiliza localmente dentro del método.
Pero, sólo por el bien de la discusión, el siguiente método usando una declaración while()
es sintácticamente correcta, "seguro" y no modificando desde una perspectiva de alcance y de referencia:
en algún lugar de la definición de clase .. .
ArrayList<String> messageList;
en alguna parte del constructor de la clase
messageList = new ArrayList<String>();
añadir un método ...
public printMessages ()
{
Iterator<String> messageIterator = messageList.iterator();
while (messageIterator.hasNext())
{
System.out.println(messageIterator.next());
}
System.out.flush();
}
duplicados de http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re – Raedwald