Eine Anleitung zu Iterator in Java

1. Einleitung

Ein Iterator ist eine von vielen Möglichkeiten, wie wir eine Sammlung durchlaufen können, und wie jede Option hat er seine Vor- und Nachteile.

Es wurde erstmals in Java 1.2 als Ersatz für Aufzählungen eingeführt und:

  • verbesserte Methodennamen eingeführt
  • ermöglichte es, Elemente aus einer Sammlung zu entfernen, über die wir iterieren
  • garantiert keine Iterationsreihenfolge

In diesem Tutorial werden wir die einfache Iterator- Oberfläche überprüfen , um zu erfahren, wie wir die verschiedenen Methoden verwenden können.

Wir werden auch die robustere ListIterator- Erweiterung überprüfen, die einige interessante Funktionen hinzufügt.

2. Die Iterator- Schnittstelle

Zu Beginn müssen wir einen Iterator aus einer Sammlung erhalten . Dies erfolgt durch Aufrufen der iterator () -Methode.

Der Einfachheit halber erhalten wir die Iterator- Instanz aus einer Liste:

List items = ... Iterator iter = items.iterator();

Die Iterator- Schnittstelle verfügt über drei Kernmethoden:

2.1. hasNext ()

Mit der Methode hasNext () kann überprüft werden, ob noch mindestens ein Element zum Durchlaufen übrig ist.

Es wurde entwickelt, um als Bedingung in while- Schleifen verwendet zu werden:

while (iter.hasNext()) { // ... }

2.2. Nächster()

Die next () -Methode kann verwendet werden, um über das nächste Element zu springen und es zu erhalten:

String next = iter.next();

Es wird empfohlen , hasNext () zu verwenden, bevor Sie versuchen, next () aufzurufen .

Iteratoren für Sammlungen garantieren keine Iteration in einer bestimmten Reihenfolge, es sei denn, eine bestimmte Implementierung sieht dies vor.

2.3. entfernen()

Wenn wir das aktuelle Element aus der Sammlung entfernen möchten , können wir Folgendes verwenden :

iter.remove();

Dies ist eine sichere Methode zum Entfernen von Elementen beim Durchlaufen einer Sammlung, ohne dass das Risiko einer ConcurrentModificationException besteht.

2.4. Vollständiges Iterator- Beispiel

Jetzt können wir sie alle kombinieren und sehen, wie wir die drei Methoden zusammen für die Sammlungsfilterung verwenden:

while (iter.hasNext()) { String next = iter.next(); System.out.println(next); if( "TWO".equals(next)) { iter.remove(); } }

So verwenden wir normalerweise einen Iterator. Wir prüfen im Voraus, ob ein anderes Element vorhanden ist, rufen es ab und führen dann eine Aktion aus.

2.5. Iterieren mit Lambda-Ausdrücken

Wie wir in den vorherigen Beispielen gesehen haben, ist es sehr ausführlich, einen Iterator zu verwenden, wenn wir nur alle Elemente durchgehen und etwas damit tun möchten.

Seit Java 8 haben wir die forEachRemaining- Methode, mit der Lambdas zur Verarbeitung verbleibender Elemente verwendet werden können:

iter.forEachRemaining(System.out::println);

3. Die ListIterator- Schnittstelle

ListIterator ist eine Erweiterung, die neue Funktionen zum Durchlaufen von Listen hinzufügt:

ListIterator listIterator = items.listIterator(items.size());

Beachten Sie, wie wir eine Startposition bereitstellen können, die in diesem Fall das Ende der Liste darstellt.

3.1. hasPrevious () und previous ()

ListIterator kann für die Rückwärtsdurchquerung verwendet werden, sodass es Entsprechungen von hasNext () und next () enthält :

while(listIterator.hasPrevious()) { String previous = listIterator.previous(); }

3.2. nextIndex () und previousIndex ()

Zusätzlich können wir Indizes und nicht tatsächliche Elemente durchlaufen:

String nextWithIndex = items.get(listIterator.nextIndex()); String previousWithIndex = items.get(listIterator.previousIndex());

Dies kann sich als sehr nützlich erweisen, wenn wir die Indizes der Objekte kennen müssen, die wir gerade ändern, oder wenn wir entfernte Elemente aufzeichnen möchten.

3.3. hinzufügen()

Die add- Methode, mit der wir, wie der Name schon sagt, ein Element vor dem Element hinzufügen können, das von next () zurückgegeben wird, und nach dem Element, das von previous () zurückgegeben wird:

listIterator.add("FOUR");

3.4. einstellen()

Die letzte erwähnenswerte Methode ist set (), mit der wir das Element ersetzen können, das beim Aufruf von next () oder previous () zurückgegeben wurde :

String next = listIterator.next(); if( "ONE".equals(next)) { listIterator.set("SWAPPED"); }

Es ist wichtig zu beachten, dass dies nur ausgeführt werden kann, wenn keine vorherigen Aufrufe zum Hinzufügen () oder Entfernen () vorgenommen wurden.

3.5. Vollständiges ListIterator- Beispiel

Wir können sie jetzt alle kombinieren, um ein vollständiges Beispiel zu erstellen:

ListIterator listIterator = items.listIterator(); while(listIterator.hasNext()) { String nextWithIndex = items.get(listIterator.nextIndex()); String next = listIterator.next(); if("REPLACE ME".equals(next)) { listIterator.set("REPLACED"); } } listIterator.add("NEW"); while(listIterator.hasPrevious()) { String previousWithIndex = items.get(listIterator.previousIndex()); String previous = listIterator.previous(); System.out.println(previous); }

In diesem Beispiel beginnen wir mit der immer ListIterator aus der Liste , dann können wir das nächste Element entweder durch den Index erhalten - was nicht den Iterator internes Stromelement nicht erhöht - oder telefonisch nächsten .

Dann können wir ein bestimmtes Element durch set ersetzen und ein neues mit add einfügen .

Nach Erreichen des Endes der Iteration können wir rückwärts gehen, um zusätzliche Elemente zu ändern oder sie einfach von unten nach oben zu drucken.

4. Fazit

Über die Iterator- Oberfläche können wir eine Sammlung während des Durchlaufs ändern, was mit einer einfachen for / while-Anweisung schwieriger ist. Dies gibt uns wiederum ein gutes Muster, das wir in vielen Methoden verwenden können, die nur die Verarbeitung von Sammlungen erfordern, während eine gute Kohäsion und eine geringe Kopplung beibehalten werden.

Schließlich ist wie immer der vollständige Quellcode bei GitHub verfügbar.