Polymorpher Unterschied (die unterste Ebene von foreach ist Iterator)
Iterator ist ein Schnittstellentyp, der sich nicht um die Art der Sammlung oder des Arrays kümmert;
for und Foreach müssen zuerst den Typ der Sammlung und sogar den Typ der Elemente in der Sammlung kennen;
Dekompilierter Code:
2. Der Unterschied zwischen Remove in foreach und Iterator
Schauen wir uns zuerst an. 1 , und in 2 wird ein Fehler gemeldet (java.util.ConcurrentModificationException)
Werfen wir zunächst einen Blick auf die Implementierung der Iteratormethode in ArrayList:
ruft new Itr() zum Generieren auf die Itr-Klasse (Iterator). Zu diesem Zeitpunkt werden die drei Parameter von Itr initialisiert.
Cursor stellt die nächste Indexposition dar (beginnend bei 0)next method () wird geworfen CheckForComodification ist gleich
modCount Änderungsanzahl (jedes Hinzufügen und Entfernen wird +1) erwartetModCount Die maximale erwartete Anzahl
1.Remove-Operation Quellcode-AnalyseDa modCount und erwartetModCount zu diesem Zeitpunkt beide 2 sind (modCount ist 2, weil es zweimal hinzugefügt wurde), wird in der ersten Schleife keine Ausnahme ausgelöst und es werden auch keine Ausnahmen ausgelöst Bei sekundären Zyklen in die erste Schleife geworfen. Nachdem die nächste Methode abgeschlossen ist, ist die if-Bedingung der Methode „remove“ im Methodenkörper der foreach-Schleife nicht erfüllt und die Schleife endet.
Zweite Schleife:
Die hasNext- und next-Methoden der zweiten Schleife können erfolgreich abgeschlossen werden. Danach wird die Methode „remove“ in den Methodenkörper der foreach-Schleife eingegeben, um Elemente zu löschen. Zu diesem Zeitpunkt wird Größe-1 zu 1. In der fastRemove-Methode wird in der Remove-Methode modCount + 1 hinzugefügt, was zu 3 wird.
Die dritte Schleife:
Dann wird in der dritten Schleife zur hasNext-Methode übergegangen. Unter normalen Umständen gibt diese Methode false zurück. Da sich die Größe zu diesem Zeitpunkt jedoch auf 1 geändert hat und der Cursor zu diesem Zeitpunkt 2 ist (der Cursor stellt die nächste Indexposition dar), sind die beiden nicht gleich und es wird ein Fehler zurückgegeben . true, daher wird in der nächsten Methode weiterhin mit der checkForComodification-Methode fortgefahren, um festzustellen, ob modCount und erwartetModCount zu diesem Zeitpunkt gleich sind. Da sich der modCount zu diesem Zeitpunkt auf 3 geändert hat, was sich vom erwarteten ModCount-Wert 2 unterscheidet, wurde hier eine ConcurrentModificationException-Ausnahme ausgelöst.
Schauen wir uns an, warum beim Löschen von „1“ keine Ausnahme ausgelöst wird:
Erste Schleife:
Wie oben, zu diesem Zeitpunkt sind modCount und erwartetModCount beide 2, also in der ersten Schleife Keines von beiden hasNext- und next-Methoden lösen Ausnahmen aus. Danach wird die Methode „remove“ in den Methodenkörper der foreach-Schleife eingegeben, um das Element zu löschen. Wie oben wird size-1 zu 1 und modCount+1 zu 3.
Zweite Schleife:
In der hasNext-Methode der zweiten Schleife ist der Cursor zu diesem Zeitpunkt 1 und die Größe ist ebenfalls 1, und sie sind gleich. Wenn die hasNext-Methode also false zurückgibt, springt sie aus der foreach-Schleife und geht nicht zur nachfolgenden next-Methode über, sodass keine Ausnahme ausgelöst wird.
2. Quellcode-Schritteruft new Itr() auf, um die Itr-Klasse (Iterator) zu generieren. Zu diesem Zeitpunkt werden die drei Parameter von Itr initialisiert.
Zu diesem Zeitpunkt wird erwartetModCount == modCount == 2 (da die Liste die Add-Methode mobilisiert, implementiert die Add-Methode die ++-Operation für modCount)
Der zweite Satz ruft die HasNext()-Methode unten auf und Gibt den nächsten Zugriff zurück. Der tiefgestellte Cursor des Elements, da es sich um die erste Schleife handelt, ist der Cursor 0 und die Größe ist 2 (0 != 2 wahr)
Die Methode next() wird in aufgerufen ③ Satz, und die Methode zum Entfernen im Methodenkörper der foreach-Schleife lautet: Wenn die Bedingung nicht erfüllt ist, endet die Schleife. Der nächste tiefgestellte Cursor des Elements, auf das zugegriffen werden soll, führt eine zweite Schleife durch, sodass der Cursor 1 ist, #🎜🎜 #size ist immer noch 2 (1 != 2 wahr)
Das entfernen( )-Methode wird in Satz ④ aufgerufen und das Element wurde erfolgreich aus der Liste gelöscht. Beachten Sie, dass beim Aufruf der Methode „remove“ modCount++ vorhanden ist. Alles zu diesem Zeitpunkt, modCount3, erwartetModCount2, size1
Das dritte Mal
Der zweite Satz ruft die unten stehende hasNext()-Methode auf und gibt die zurück next item Greifen Sie zum zweiten Mal auf den tiefgestellten Cursor des Elements zu und wiederholen Sie die Schleife, sodass der Cursor 2 und die Größe 1 beträgt
Der ③-Satz ruft die next()-Methode auf. Beachten Sie, dass der erste Satz in next() ist. Die Methode besteht darin, checkForComodification() aufzurufen. Da modCount(3) != erwartetModCount(2) wird eine Ausnahme ausgelöst.
3. Warum sind die unteren Ebenen alle Iteratoren und warum meldet foreach einen Fehler
Wenn die Schleife endet while (iterator.hasNext()) prüft, ob das nächste Element vorhanden ist, nachdem Remove 2 abgeschlossen ist. Bei der nächsten Eingabe ist der Cursor immer noch 1 und die Größe ist ebenfalls 1.
#🎜 🎜## 🎜🎜#
3. Quellcode-Methode anzeigen
#🎜🎜 #
Das obige ist der detaillierte Inhalt vonWas ist der Unterschied zwischen der Verwendung von foreach und iterator zum Löschen von Elementen beim Durchlaufen von Java ArrayList?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!