Ich spiele mit Code für meinen College-Kurs herum und ändere eine Methode von
%Vor%An:
%Vor%Aber die neue Methode gibt weiterhin einen Fehler bei gleichzeitiger Änderung. Wie kann ich das umgehen und warum passiert es?
Dies liegt daran, dass Sie die Liste nach dem Ausführen von remove()
weiter durchsuchen.
Sie lesen und schreiben gleichzeitig in die Liste, was den Vertrag des Iterators bricht, der der foreach-Schleife zugrunde liegt.
Iterator.remove()
Es wird wie folgt beschrieben:
Gibt das nächste Element in der Iteration zurück.
Wirf
NoSuchElementException
, wenn die Iteration keine Elemente mehr enthält.
Sie können Iterator.hasNext()
verwenden, um zu prüfen, ob ein nächstes Element verfügbar ist.
foreach
construct verwendet eine zugrunde liegende Iterator
.
In der zweiten Methode iterieren Sie auch nach dem Entfernen eines Elements aus der Liste. Dies führt zu der Ausnahme, die Sie sehen. Sehen Sie sich diese Aussage aus ConcurrentModificationException
documentation an:
Zum Beispiel ist es generell nicht zulässig, dass ein Thread modifiziert wird eine Sammlung, während ein anderer Thread darüber iteriert. Im Algemeinen, Die Ergebnisse der Iteration sind unter diesen Umständen nicht definiert. Einige Iterator - Implementierungen (einschließlich der allgemeinen Zwecksammlungsimplementierungen, die von der JRE bereitgestellt werden), können dies wählen Werfen Sie diese Ausnahme aus, wenn dieses Verhalten erkannt wird.
Dieser Fehler tritt auf, weil Sie versuchen, die Größe einer Sammlung während der Iteration zu ändern. Wenn Sie 10 Schüler haben, beginnen Sie Ihre Schleife mit 10 Wiederholungen. Wie viele Iterationen müssen nach dem Entfernen eines Schülers noch ausgeführt werden? Die Antwort hängt natürlich davon ab, wo Sie Ihren Schüler aus der Liste entfernt haben und wo Sie sich gerade befinden. Offensichtlich kann Java das nicht wissen.
Um dies zu umgehen, müssen Sie einen Iterator verwenden. Sie können dies wie folgt erreichen:
%Vor% Sie dürfen ein Element aus students
collection nicht entfernen, wenn Sie es durchlaufen.
Diese Ausnahme kann von Methoden ausgelöst werden, die gleichzeitige Änderungen eines Objekts erkannt haben, wenn eine solche Änderung nicht zulässig ist.
Zum Beispiel ist es im Allgemeinen nicht zulässig, dass ein Thread eine Collection ändert, während ein anderer Thread darüber iteriert. Im Allgemeinen sind die Ergebnisse der Iteration unter diesen Umständen nicht definiert.
Versuchen Sie, zu
zu wechseln %Vor%Sie sollten Objekte während der Verwendung nicht aus einer Sammlung löschen Eine for-each-Anweisung - dies verursacht Ausnahmen, da Ihr Iterator im Verlauf seiner Iterationen einer geänderten Sammlung gegenübersteht. (die for-Schleife) Verwenden Sie entweder eine reguläre for-Schleife (für int i = 0; i & lt; 100; i ++) usw. oder halten Sie die zu entfernenden Objekte in einer Liste und entfernen Sie sie außerhalb der for-Schleife.
Außerdem entfernen Sie das Objekt nach Index, wobei der Index lautet: 0, 1, 2 aber Index sollte tatsächlich der Index des Schülers sein.
Sie dürfen ein Element nicht aus Ihrer Sammlung entfernen, während Sie darüber iterieren. Der Iterator erkennt während seiner Verwendung eine Strukturänderung und löst die Ausnahme aus. Viele Sammlungen sind so implementiert.
Verwenden Sie stattdessen den Iterator direkt:
%Vor%