Hier gibt es zwei Probleme:
Das erste Problem ist das Hinzufügen zu einem, Collection
nachdem ein Iterator
zurückgegeben wurde. Wie bereits erwähnt, gibt es kein definiertes Verhalten, wenn der Basiswert Collection
geändert wird, wie in der Dokumentation für Folgendes angegeben Iterator.remove
:
... Das Verhalten eines Iterators ist nicht angegeben, wenn die zugrunde liegende Auflistung während der Iteration auf andere Weise als durch Aufrufen dieser Methode geändert wird.
Das zweite Problem ist, dass es keine Garantie für die Reihenfolge der Iteration gibt, selbst wenn eine erhalten werden Iterator
könnte und dann zu demselben Element zurückkehrt, an Iterator
dem sie sich befand, wie in der Collection.iterator
Methodendokumentation angegeben:
... Es gibt keine Garantien für die Reihenfolge, in der die Elemente zurückgegeben werden (es sei denn, diese Sammlung ist eine Instanz einer Klasse, die eine Garantie bietet).
Nehmen wir zum Beispiel an, wir haben die Liste [1, 2, 3, 4]
.
Nehmen wir an, es 5
wurde hinzugefügt, als das Iterator
bei war 3
, und irgendwie erhalten wir ein Iterator
, von dem aus die Iteration fortgesetzt werden kann 4
. Es gibt jedoch keine Garantie, 5
die danach kommt 4
. Die Iterationsreihenfolge kann sein [5, 1, 2, 3, 4]
- dann wird der Iterator das Element immer noch verfehlen 5
.
Da es keine Garantie für das Verhalten gibt, kann man nicht davon ausgehen, dass die Dinge auf eine bestimmte Weise geschehen werden.
Eine Alternative könnte darin bestehen, eine separate zu haben, Collection
zu der die neu erstellten Elemente hinzugefügt werden können, und diese Elemente dann zu durchlaufen:
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);
}
Bearbeiten
Wenn Sie die Antwort von Avi näher erläutern , können Sie die Elemente, über die wir iterieren möchten, in eine Warteschlange stellen und die Elemente entfernen, während die Warteschlange Elemente enthält. Dies ermöglicht die "Iteration" über die neuen Elemente zusätzlich zu den ursprünglichen Elementen.
Schauen wir uns an, wie es funktionieren würde.
Konzeptionell, wenn wir die folgenden Elemente in der Warteschlange haben:
[1, 2, 3, 4]
Und wenn wir entfernen 1
, entscheiden wir uns hinzuzufügen 42
, die Warteschlange wird wie folgt sein:
[2, 3, 4, 42]
Da es sich bei der Warteschlange um eine FIFO -Datenstruktur (First-In, First-Out) handelt, ist diese Reihenfolge typisch. (Wie in der Dokumentation für die Queue
Schnittstelle angegeben, ist dies keine Notwendigkeit von a Queue
. Nehmen Sie den Fall, bei PriorityQueue
dem die Elemente nach ihrer natürlichen Reihenfolge geordnet werden, das ist also kein FIFO.)
Das folgende Beispiel verwendet ein LinkedList
(welches a ist Queue
), um alle Elemente zusammen mit zusätzlichen Elementen, die während des Enthärtens hinzugefügt wurden, durchzugehen. Ähnlich wie im obigen Beispiel wird das Element 42
hinzugefügt, wenn das Element 2
entfernt wird:
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);
}
Das Ergebnis ist folgendes:
1
2
3
4
42
Wie erhofft erschien das Element, 42
das hinzugefügt wurde, als wir schlugen 2
.