Są tu dwa problemy:
Pierwszą kwestią jest dodanie do Collectionpo Iteratorzwróceniu an . Jak wspomniano, nie ma zdefiniowanego zachowania, gdy element bazowy Collectionjest modyfikowany, jak wspomniano w dokumentacji Iterator.remove:
... Zachowanie iteratora jest nieokreślone, jeśli bazowa kolekcja zostanie zmodyfikowana, podczas gdy iteracja jest w toku w inny sposób niż wywołanie tej metody.
Druga kwestia polega na tym, że nawet jeśli Iteratormożna było uzyskać a, a następnie powrócić do tego samego elementu, w którym się Iteratorznajdował, nie ma gwarancji co do kolejności iteracji, jak zaznaczono w Collection.iteratordokumentacji metody:
... Nie ma żadnych gwarancji co do kolejności zwracania elementów (chyba że ta kolekcja jest instancją jakiejś klasy, która daje gwarancję).
Na przykład, powiedzmy, że mamy listę [1, 2, 3, 4] .
Powiedzmy, że 5został dodany, gdy Iteratorbył w 3, i jakoś otrzymujemy, Iteratorktóry może wznowić iterację od 4. Jednak nie ma gwarancji, która 5nastąpi później 4. Kolejność iteracji może być taka [5, 1, 2, 3, 4]- wtedy iterator nadal będzie pomijał element5 .
Ponieważ nie ma gwarancji zachowania, nie można zakładać, że coś wydarzy się w określony sposób.
Jedną z alternatyw może być oddzielne, Collectiondo którego można dodawać nowo utworzone elementy, a następnie iterowanie po tych elementach:
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);
}
Edytować
Opierając się na odpowiedzi Avi , możliwe jest umieszczanie w kolejce elementów, które chcemy iterować, do kolejki i usuwanie elementów, gdy kolejka zawiera elementy. Pozwoli to na „iterację” po nowych elementach oprócz elementów oryginalnych.
Spójrzmy, jak by to działało.
Koncepcyjnie, jeśli w kolejce mamy następujące elementy:
[1, 2, 3, 4]
A kiedy usuniemy 1, zdecydujemy się dodać 42, kolejka będzie wyglądać następująco:
[2, 3, 4, 42]
Ponieważ kolejka jest strukturą danych FIFO (pierwsze weszło , pierwsze wyszło), ta kolejność jest typowa. (Jak zauważono w dokumentacji Queueinterfejsu, nie jest to konieczne a Queue. Weźmy przykładPriorityQueue którym porządkuje elementy według ich naturalnego porządku, więc nie jest to FIFO).
Poniżej znajduje się przykład użycia a LinkedList(czyli a Queue) w celu przejścia przez wszystkie elementy wraz z dodatkowymi elementami dodanymi podczas dekolekcji. Podobnie jak w powyższym przykładzie, element 42jest dodawany po usunięciu elementu 2:
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);
}
Wynik jest następujący:
1
2
3
4
42
Zgodnie z oczekiwaniami pojawił się element, 42który został dodany po trafieniu 2.