Hay dos problemas aquí:
El primer problema es agregar a un Collection
después de que Iterator
se devuelve un. Como se mencionó, no hay un comportamiento definido cuando Collection
se modifica el subyacente , como se indica en la documentación para Iterator.remove
:
... El comportamiento de un iterador no se especifica si la colección subyacente se modifica mientras la iteración está en progreso de cualquier otra forma que no sea llamando a este método.
El segundo problema es que, incluso si se Iterator
pudiera obtener un, y luego regresar al mismo elemento en el que Iterator
estaba, no hay garantía sobre el orden de la iteración, como se indica en la Collection.iterator
documentación del método:
... No hay garantías con respecto al orden en que se devuelven los elementos (a menos que esta colección sea una instancia de alguna clase que proporcione una garantía).
Por ejemplo, digamos que tenemos la lista [1, 2, 3, 4]
.
Digamos que 5
se agregó cuando Iterator
estaba en 3
, y de alguna manera, obtenemos un Iterator
que puede reanudar la iteración 4
. Sin embargo, no hay garantía de que 5
vendrá después 4
. El orden de iteración puede ser [5, 1, 2, 3, 4]
, entonces el iterador aún perderá el elemento 5
.
Como no hay garantía para el comportamiento, no se puede asumir que las cosas sucederán de cierta manera.
Una alternativa podría ser tener un elemento separado Collection
al que se puedan agregar los elementos recién creados y luego iterar sobre esos elementos:
Collection<String> list = Arrays.asList(new String[]{"Hello", "World!"});
Collection<String> additionalList = new ArrayList<String>();
for (String s : list) {
additionalList.add(s);
}
for (String s : additionalList) {
System.out.println(s);
}
Editar
Abundando en la respuesta de Avi , es posible hacer cola los elementos que queremos para repetir en una cola, y retirar los elementos, mientras que la cola tiene elementos. Esto permitirá la "iteración" sobre los nuevos elementos además de los elementos originales.
Veamos cómo funcionaría.
Conceptualmente, si tenemos los siguientes elementos en la cola:
[1, 2, 3, 4]
Y, cuando eliminemos 1
, decidamos agregar 42
, la cola quedará como la siguiente:
[2, 3, 4, 42]
Como la cola es una estructura de datos FIFO (primero en entrar , primero en salir), este orden es típico. (Como se indica en la documentación de la Queue
interfaz, esto no es una necesidad de a Queue
. Tomemos el caso de PriorityQueue
que ordena los elementos por su orden natural, por lo que no es FIFO).
El siguiente es un ejemplo que usa a LinkedList
(que es a Queue
) para pasar por todos los elementos junto con los elementos adicionales agregados durante la eliminación de la cola. Al igual que en el ejemplo anterior, el elemento 42
se agrega cuando 2
se elimina el elemento :
Queue<Integer> queue = new LinkedList<Integer>();
queue.add(1);
queue.add(2);
queue.add(3);
queue.add(4);
while (!queue.isEmpty()) {
Integer i = queue.remove();
if (i == 2)
queue.add(42);
System.out.println(i);
}
El resultado es el siguiente:
1
2
3
4
42
Como era de esperar, apareció el elemento 42
que se agregó cuando golpeamos 2
.