„Hallo, Amigo!“

„Hallo, Ellie!“

„Heute möchte ich Ihnen etwas über Iteratoren erzählen.“

„Iteratoren wurden praktisch gleichzeitig mit Sammlungen erfunden. Der Hauptzweck von Sammlungen besteht darin, Elemente zu speichern, und der Hauptzweck eines Iterators besteht darin, diese Elemente einzeln abzurufen.“

„Was ist so schwierig daran, eine Reihe von Elementen zu bekommen?“

„Erstens haben die Elemente in einigen Sammlungen, wie zum Beispiel Set, keine festgelegte Reihenfolge und/oder die Reihenfolge ändert sich ständig.“

„Zweitens können einige Datenstrukturen Objekte auf sehr komplexe Weise speichern: in verschiedenen Gruppen, Listen usw. Mit anderen Worten: Alle Elemente der Reihe nach auszugeben, wäre eine nicht triviale Aufgabe.“

„Drittens neigen Sammlungen dazu, sich zu ändern. Angenommen, Sie möchten den gesamten Inhalt einer Sammlung anzeigen, aber mitten in der Ausgabe wechselt die JVM zu einem anderen Thread, der die Hälfte der Elemente der Sammlung ersetzt. Anstelle der Ausgabe erhalten Sie also wer weiß was.“

"Hmm..."

"Aber! Das sind genau die Art von Problemen, die ein Iterator lösen kann. Ein Iterator ist ein spezielles Objekt innerhalb einer Sammlung, das einerseits Zugriff auf alle seine privaten Daten hat und seine interne Struktur kennt, und andererseits , implementiert die öffentliche Iterator-Schnittstelle, die jedem zeigt, wie man damit arbeitet.

„Einige Iteratoren verfügen über ein internes Array, in das alle Elemente der Sammlung kopiert werden, wenn der Iterator erstellt wird. Dadurch wird sichergestellt, dass spätere Änderungen an der Sammlung keinen Einfluss auf die Anzahl oder Reihenfolge der Elemente haben.“

„Ich glaube, Sie sind darauf gestoßen, als Sie mit for every gearbeitet haben. Sie können eine Sammlung nicht gleichzeitig durchlaufen und gleichzeitig Elemente daraus entfernen. Das liegt alles genau an der Funktionsweise eines Iterators.“

„In den neuen Sammlungen, die der Parallelitätsbibliothek hinzugefügt wurden, wurde der Iterator überarbeitet, um dieses Problem zu beseitigen.“

„Ich möchte Sie daran erinnern, wie ein Iterator funktioniert.“

„Java verfügt über eine spezielle Iterator-Schnittstelle. Hier sind seine Methoden:“

Methoden der Iterator<E>-Schnittstelle Beschreibung
boolean hasNext() Überprüft, ob weitere Elemente vorhanden sind
E next() Gibt das aktuelle Element zurück und wechselt zum nächsten.
void remove() Entfernt das aktuelle Element

„Mit einem Iterator können Sie nacheinander alle Elemente einer Sammlung abrufen. Es ist logischer, sich einen Iterator als etwas wie einen InputStream vorzustellen – er enthält alle Daten, aber seine Aufgabe besteht darin, sie sequentiell auszugeben.“

„Die   Methode next () gibt das nächste Element in der Sammlung zurück.“

„Mit der Methode hasNext () wird überprüft, ob noch weitere Elemente vorhanden sind.“

„Und remove () entfernt das aktuelle Element.“

"Irgendwelche Fragen?"

„Warum haben die Methoden so seltsame Namen? Warum nicht isEmpty() und getNextElement()?“

„Wäre das nicht sinnvoller?“

„Es wäre sinnvoller, aber die Namen stammen aus der Sprache C++, wo Iteratoren früher auftauchten.“

„Ich verstehe. Lass uns weitermachen.“

„Neben einem Iterator gibt es auch die Iterable-Schnittstelle, die von allen Sammlungen implementiert werden muss, die Iteratoren unterstützen. Sie verfügt über eine einzige Methode:“

Methoden der Iterable<T>-Schnittstelle Beschreibung
Iterator<T>iterator() Gibt ein Iteratorobjekt zurück

„Sie können diese Methode für jede Sammlung verwenden, um ein Iteratorobjekt dazu zu bringen, seine Elemente zu durchlaufen. Lassen Sie uns alle Elemente in einem TreeSet durchgehen :“

Beispiel
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();

while (iterator.hasNext())
{
 String item = iterator.next();
 System.out.println(item);
}

„Die Verwendung eines solchen Iterators ist nicht sehr praktisch – es gibt zu viel überflüssigen und offensichtlichen Code. Die Situation wurde einfacher, als die for-each- Schleife in Java erschien.“

„Jetzt ist dieser Code viel kompakter und lesbarer:“

Vor Nach
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();

while (iterator.hasNext())
{
 String item = iterator.next();
 System.out.println(item);
}
TreeSet<String> set = new TreeSet<String>();

for(String item : set)
{
 System.out.println(item);
}

„Das ist der gleiche Code! Der Iterator wird in beiden Fällen verwendet.“

„Es ist nur so, dass seine Verwendung in der for-each- Schleife verborgen ist. Beachten Sie, dass der Code auf der rechten Seite überhaupt keinen roten Text enthält. Die Verwendung des Iterators ist vollständig verborgen.“

„Eine for-each- Schleife kann für alle Objekte verwendet werden, die Iteratoren unterstützen. Mit anderen Worten: Sie können Ihre eigene Klasse schreiben, ihr die Methode iterator () hinzufügen und ihre Objekte in einem for-each- Konstrukt verwenden.“

„Wow! Natürlich habe ich keine Lust, meine eigenen Sammlungen und Iteratoren zu schreiben, aber die Aussicht ist trotzdem verlockend. Ich werde es mir notieren.“

Darüber hinaus gibt es einen weiteren beliebten Iteratortyp, der sogar über eine eigene Schnittstelle verfügt. Ich spreche von einem Iterator für Listen, nämlich ListIterator .

„Unabhängig von ihrer Implementierung behalten Listen die Reihenfolge der Elemente bei, was die Arbeit mit ihnen über einen Iterator etwas komfortabler macht.“

„Hier sind die Methoden der ListIterator <E>-Schnittstelle:“

Methode Beschreibung
boolean hasNext() Überprüft, ob weitere Elemente vor Ihnen liegen.
E next() Gibt das nächste Element zurück.
int nextIndex() Gibt den Index des nächsten Elements zurück
void set(E e) Ändert den Wert des aktuellen Elements
boolean hasPrevious() Überprüft, ob sich dahinter irgendwelche Elemente befinden.
E previous() Gibt das vorherige Element zurück
int previousIndex() Gibt den Index des vorherigen Elements zurück
void remove() Entfernt das aktuelle Element
void add(E e) Fügt ein Element am Ende der Liste hinzu.

„Mit anderen Worten: Hier können wir uns sowohl vorwärts als auch rückwärts bewegen. Und es gibt noch ein paar andere kleine Features.“

„Nun, das ist ein interessantes Zeug. Wo wird es verwendet?“

„Angenommen, Sie möchten sich in einer verknüpften Liste hin und her bewegen. Die Get-Operation wird ziemlich langsam sein, aber die Next()-Operation wird sehr schnell sein.“

„Hmm. Du hast mich überzeugt. Ich werde es mir merken.“

„Danke, Ellie!“