Java Tutorial #49

Java Iterator

2021-05-25

Thema in Kurzform

Der Iterator ist ein generisches Interface, mit dem alle Elemente einer Sammlung sequenziell durchlaufen werden können. Der Iterator steht allen Sammlungsklassen der Java-API zur Verfügung. Wie genau der Iterator funktioniert, zeigen wir dir hier.

// Code in Kurzform
Iterator<Elementtyp> it = sammlung.iterator();
while(it.hasNext()){
    Elementtyp e = it.next();
    if(e.getValue() < 10) {
        it.remove();
    }
}

Was ist ein Iterator?

Das Durchlaufen der einzelnen Elemente einer Sammlung ("iterieren") gehört zu den Kernaufgaben im Umgang mit Datenstrukturen. Um diesen Job zu erledigen, stehen uns verschiedene Schleifentypen zur Verfügung. 

In Java gibt es neben den Schleifen noch eine weitere Art, die Elemente einer Sammlung zu durchlaufen: Der Iterator

Der Iterator ist ein generisches Interface, das es mit speziellen Methoden ermöglicht, alle Elemente einer Sammlung sequenziell zu durchlaufen. Der Iterator steht allen Sammlungsklassen der Java-API zur Verfügung.

Wie genau der Iterator funktioniert, zeigen wir dir jetzt.

Werbung

Wie funktioniert der Iterator?

Das Iterator-Interface befindet sich im Paket java.util und muss entsprechend importiert werden:

import java.util.Iterator;

Bevor wir eine Sammlung mit einem Iterator durchlaufen können, müssen wir zuerst ein Iterator-Objekt erhalten. Hierzu besitzt jede Collection-Klasse eine spezielle Methode namens iterator(), die ein zur Sammlung passendes Iterator-Objekt zurückliefert: 

Iterator<Film> it = sammlung.iterator();

In diesem Beispiel erhalten wir einen Iterator für eine Sammlung von Film-Objekten. Der Iterator ist ein generischer Typ und sein jeweiliger Typ-Parameter muss vom gleichen Typ sein wie bei der Sammlung, die wir mit ihm durchlaufen wollen. 

Auf dem Iterator-Objekt stehen dann folgende Methoden bereit: 

Methoden Iterator
boolean hasNext() Prüft, ob es ein nächstes Element gibt 
void next() liefert das nächste Element zurück
remove() Löscht das aktuelle Element

Das "Durchiterieren" der Sammlung läuft so ab:

Iterator<Film> it = sammlung.iterator();
while(it.hasNext()){
    Film f = it.next();
    System.out.println(f.getName());
}

Erklärung: Die Methode hasNext() prüft, ob es ein jeweils nächstes Element in der Sammlung gibt. Falls ja, wird true zurückgeliefert. Innerhalb der Schleife wird mit next() das nächste Element dann zurückgeliefert. Der Pointer wandert danach eine Position auf das nächste Objekt. Mit dieser Technik arbeiten wir uns Element für Element durch die gesamte Sammlung. 

Die Infografik zeigt diesen Vorgang:

Infografik Java Iterator

Elemente löschen 

Zum Löschen von Elementen während der Iteration kommt die Methode remove() zum Einsatz:

Angenommen, wird möchten alle Filme aus der Sammlung entfernen, die vor dem Jahr 2000 datiert sind, dann können wir das so erledigen:

Iterator<Film> it = sammlung.iterator();
while(it.hasNext()){
    Film f = it.next();
    if(f.getDatum() < 2000) {
        it.remove();
    }
}

Vorteile des Iterators

Wieso brauchen wir zum Löschen während des Durchlaufens der Sammlung extra einen Iterator? Können wir das nicht auch mit den hergebrachten Schleifenkonstruktionen durchführen? Immerhin verfügen die Sammlungsklassen eine eigene remove()-Methode.

Gehen wir der Sache auf den Grund. 

Löschen in einer foreach-Schleife

Versuchen wir, Elemente einer Sammlung innerhalb einer foreach-Schleife zu löschen, erhalten als Resultat eine ConcurrentModificationException:

for(Film sV : sammlung) {
    if(sV.getDatum() < 2000){
        sammlung.remove(sV); // ConcurrentModificationException
    }
}

Es ist also nicht möglich, Elemente einer Sammlung während des Durchlaufens mit einer foreach-Schleife zu löschen.

Löschen in einer for-Schleife 

Und wie sieht es mit einer index-gesteuerten for-Schleife aus? Technisch gesehen würde das Löschen von Elementen funktionieren, doch sollten wir es trotzdem sein lassen. Entfernt man nämlich Elemente einer Sammlung, ändern sich damit auch die Indizes. So kann es schnell passieren, dass wir eine Schleife programmieren, die nach Manipulation an der zugrunde liegenden Sammlung mit falschen Indizes arbeitet. 

Außerdem wird natürlich die Größe der Sammlung nach einem Löschvorgang reduziert, was Einfluss auf die Schleifensteuerrung hat. Hier ein Beispiel:

LinkedList<String> x = new LinkedList<>();
x.add("Phobos");
x.add("Deimos");

for(int i = 0; i < x.size(); i++){
    if(x.get(i).endsWith("s")) {
        x.remove(i);
    }
}
System.out.println(x); // [Deimos]

Fazit

Fassen wir die Unterschiede zwischen Schleifen und dem Iterator also zusammen: 

Iterations-Typ Elemente löschen Einsatz
foreach-Schleife  nein bei allen Sammlungen 
for-Schleife möglich, aber nicht empfohlen nur bei index-gesteuerte Sammlungen
Iterator ja bei allen Sammlungen
Werbung

Java lernen

Werde zum Java Profi!

PHP Lernen

Lerne serverbasierte Programmierung

JavaScript lernen

Skille dein Webcoding

FALCONBYTE.NET

Handmade with 🖤️

© 2018-2023 Stefan E. Heller

Impressum | Datenschutz | Changelog

Falconbyte Youtube Falconbyte GitHub facebook programmieren lernen twitter programmieren lernen discord programmieren lernen