logo

Iteratoren in Java

Ein Java-Cursor ist ein Iterator, der verwendet wird, um die Elemente eines Collection- oder Stream-Objekts einzeln zu iterieren, zu durchlaufen oder abzurufen. In diesem Artikel erfahren Sie mehr über Java-Iteratoren und ihre Funktionsweise.

Java-Cursor

Arten von Cursorn in Java

Es gibt drei Cursor in Java, wie unten erwähnt:



  1. Iterator
  2. Aufzählung
  3. ListIterator

Notiz: SplitIterator kann auch als Cursor betrachtet werden, da es sich nur um einen Typ von Iterator handelt.

1. Iterator

Iteratoren in Java werden in verwendet Sammlungsrahmen um Elemente einzeln abzurufen. es ist ein Universal- Iterator, da wir ihn auf jedes Collection-Objekt anwenden können. Durch die Verwendung von Iterator können wir sowohl Lese- als auch Entfernungsvorgänge ausführen. Es handelt sich um eine verbesserte Version von Enumeration mit der zusätzlichen Funktionalität, ein Element zu entfernen.

Der Iterator muss immer dann verwendet werden, wenn wir Elemente in allen im Collection-Framework implementierten Schnittstellen wie Set, List, Queue, Deque und allen implementierten Klassen der Map-Schnittstelle aufzählen möchten. Der Iterator ist der nur Cursor für das gesamte Sammlungs-Framework verfügbar. Ein Iteratorobjekt kann durch Aufrufen von erstellt werden Iterator() Methode, die in der Collection-Schnittstelle vorhanden ist.



Syntax

Iterator itr = c.  iterator  ();>

Notiz: Hier ist c ein beliebiges Collection-Objekt. itr ist vom Typ Iterator-Schnittstelle und bezieht sich auf c.

Java-Sortierzeichenfolgen

Methoden der Iteratorschnittstelle in Java

Die Iteratorschnittstelle definiert drei Methoden wie unten aufgeführt:

1. hasNext(): Gibt true zurück, wenn die Iteration mehr Elemente enthält.



public boolean hasNext();>

2. next(): Gibt das nächste Element in der Iteration zurück. Es wirft NoSuchElementException wenn kein Element mehr vorhanden ist.

public Object next();>

3. Remove(): Entfernt das nächste Element in der Iteration. Diese Methode kann nur einmal pro Aufruf von next() aufgerufen werden.

public void remove();>

Notiz: entfernen() Die Methode kann zwei Ausnahmen auslösen, und zwar wie folgt:

  • UnsupportedOperationException : Wenn der Entfernungsvorgang von diesem Iterator nicht unterstützt wird
  • Illegale staatliche Ausnahme : Wenn die nächste Methode noch nicht aufgerufen wurde oder die Remove-Methode bereits nach dem letzten Aufruf der nächsten Methode aufgerufen wurde.

Wie funktioniert der Java-Iterator intern?

In diesem Abschnitt werden wir versuchen zu verstehen, wie Java Iterator und seine Methoden intern funktionieren. Nehmen wir das folgende LinkedList-Objekt, um diese Funktionalität zu verstehen.

List cities = new LinkedList();  cities.add('G-1');  cities.add('G-2');  cities.add('G-3');  .  .  .  cities.add('G-n');>

Lassen Sie uns nun ein Iterator-Objekt für das List-Objekt erstellen, wie unten gezeigt:

Iterator citiesIterator = cities.iterator();>

Der CitiesIteartor-Iterator sieht folgendermaßen aus:

Java-Iterator Schritt 1

Hier zeigt der Cursor des Iterators vor das erste Element der Liste.

Jetzt führen wir den folgenden Codeausschnitt aus.

citiesIterator.hasNext(); citiesIterator.next();>
Java-Iterator Schritt 2

Wenn wir den obigen Codeausschnitt ausführen, zeigt der Cursor des Iterators auf das erste Element in der Liste, wie im obigen Diagramm gezeigt.

Jetzt führen wir den folgenden Codeausschnitt aus.

citiesIterator.hasNext(); citiesIterator.next();>
Java-Iterator Schritt 3

Wenn wir den obigen Codeausschnitt ausführen, zeigt der Cursor des Iterators auf das zweite Element in der Liste, wie im obigen Diagramm gezeigt. Führen Sie diesen Vorgang aus, um den Cursor des Iterators zum Endelement der Liste zu bringen.

Java-Iterator-Schritt Nr

Wenn wir nach dem Lesen des letzten Elements den folgenden Codeausschnitt ausführen, wird ein falscher Wert zurückgegeben.

citiesIterator.hasNext();>
Java-Iterator am Ende

Da der Cursor des Iterators auf das letzte Element der Liste zeigt, gibt die Methode hasNext() einen falschen Wert zurück.

Notiz: Nachdem wir alle diese Diagramme betrachtet haben, können wir sagen, dass Java Iterator nur die Vorwärtsrichtungsiteration unterstützt, wie im folgenden Diagramm gezeigt. Daher wird er auch als unidirektionaler Cursor bezeichnet.

String in int analysieren
Funktionsweise des Java-Iterators

Beispiel

Java
// Java program to Demonstrate Iterator // Importing ArrayList and Iterator classes // from java.util package import java.util.ArrayList; import java.util.Iterator; // Main class public class Test { // Main driver method public static void main(String[] args) { // Creating an ArrayList class object // Declaring object of integer type ArrayList al = neue ArrayList (); // Iterieren über die Liste for (int i = 0; i< 10; i++) al.add(i); // Printing the elements in the List System.out.println(al); // At the beginning itr(cursor) will point to // index just before the first element in al Iterator itr = al.iterator(); // Überprüfen des nächsten Elements, wobei // die Bedingung wahr bleibt, bis ein einzelnes Element // in der Liste vorhanden ist, mit der Methode hasnext() while (itr.hasNext()) { // Cursor zum nächsten Element bewegen int i = itr.next( ); // Elemente einzeln abrufen System.out.print(i + ' '); // Ungerade Elemente entfernen if (i % 2 != 0) itr.remove(); } // Befehl für die nächste Zeile System.out.println(); // Drucken der Elemente innerhalb des Objekts System.out.println(al); } }>

Ausgabe
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 0 1 2 3 4 5 6 7 8 9 [0, 2, 4, 6, 8]>

SplitIterator

Spliteratoren dienen wie andere Iteratoren dazu, die Elemente einer Quelle zu durchlaufen. Eine Quelle kann eine sein Sammlung , ein IO-Kanal oder eine Generatorfunktion. Es ist in JDK 8 enthalten und unterstützt neben der sequentiellen Traversierung auch eine effiziente parallele Traversierung (parallele Programmierung). Die Java Spliterator-Schnittstelle ist ein interner Iterator, der den Stream in kleinere Teile aufteilt. Diese kleineren Teile können parallel bearbeitet werden.

Notiz: In der realen Programmierung müssen wir Spliterator möglicherweise nie direkt verwenden. Im Normalbetrieb verhält es sich genauso wie Java Iterator.

Vorteile von Java Iterator

  • Wir können es für jede Collection-Klasse verwenden.
  • Es unterstützt sowohl READ- als auch REMOVE-Operationen.
  • Es handelt sich um einen universellen Cursor für die Sammlungs-API.
  • Methodennamen sind einfach und leicht zu verwenden.

Einschränkungen des Java-Iterators

Außerdem gibt es bestimmte Einschränkungen von Iterator, die wie folgt aufgeführt sind:

  • Bei CRUD-Operationen werden CREATE- und UPDATE-Operationen NICHT unterstützt.
  • Es unterstützt nur die Iteration in Vorwärtsrichtung, bei der es sich um einen unidirektionalen Iterator handelt.
  • Im Vergleich zu Spliterator unterstützt es NICHT die parallele Iteration von Elementen, was bedeutet, dass nur sequentielle Iteration unterstützt wird.
  • Im Vergleich zu Spliterator unterstützt es KEINE bessere Leistung bei der Iteration großer Datenmengen.

2. Aufzählung

Es handelt sich um eine Schnittstelle zum Abrufen von Elementen älterer Sammlungen (Vector, Hashtable). Enumeration ist der erste Iterator aus JDK 1.0, Reste sind in JDK 1.2 mit mehr Funktionalität enthalten. Aufzählungen werden auch verwendet, um die Eingabeströme für a anzugeben SequenceInputStream . Wir können durch Aufrufen ein Enumeration-Objekt erstellen Elemente() Methode der Vektorklasse für ein beliebiges Vektorobjekt

Syntax

// Here 'v' is an Vector class object. e is of // type Enumeration interface and refers to 'v' Enumeration e =   v  .  elements  ();>

Es gibt zwei Methoden in der Enumeration-Schnittstelle, nämlich:

1. öffentlicher boolescher Wert hasMoreElements(): Diese Methode testet, ob diese Aufzählung mehr Elemente enthält oder nicht.

2. öffentliches Objekt nextElement(): Diese Methode gibt das nächste Element dieser Aufzählung zurück. Es löst eine NoSuchElementException aus, wenn kein weiteres Element vorhanden ist

Beispiel

Java
// Java program to demonstrate Enumeration // Importing Enumeration and Vector classes // from java.util package import java.util.Enumeration; import java.util.Vector; // Main class public class Test { // Main driver method public static void main(String[] args) { // Creating a vector object Vector v = new Vector(); // Iterating over vector object for (int i = 0; i < 10; i++) v.addElement(i); // Printing elements in vector object System.out.println(v); // At beginning e(cursor) will point to // index just before the first element in v Enumeration e = v.elements(); // Checking the next element availability where // condition holds true till there is a single // element // remaining in the List while (e.hasMoreElements()) { // Moving cursor to next element int i = (Integer)e.nextElement(); // Print above elements in object System.out.print(i + ' '); } } }>

Ausgabe
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 0 1 2 3 4 5 6 7 8 9>

Für die Aufzählung gelten folgende Einschränkungen:

  • Aufzählung ist für Vermächtnis Nur Klassen (Vector, Hashtable). Daher ist es kein universeller Iterator.
  • Entfernungsvorgänge können nicht mithilfe der Aufzählung durchgeführt werden.
  • Es ist nur eine Iteration in Vorwärtsrichtung möglich.

Ähnlichkeiten zwischen Java-Enumeration und Iterator

  • Beide sind Java-Cursor.
  • Beide werden verwendet, um eine Sammlung von Objektelementen einzeln zu iterieren.
  • Beide unterstützen den READ- oder Retrieval-Vorgang.
  • Beide sind unidirektionale Java-Cursor, was bedeutet, dass sie nur Vorwärtsrichtungsiteration unterstützen.

Unterschiede zwischen Java-Enumeration und Iterator

Die folgende Tabelle beschreibt die Unterschiede zwischen Java Enumeration und Iterator:

AufzählungIterator
Eingeführt in Java 1.0Eingeführt in Java 1.2
Legacy-SchnittstelleKeine Legacy-Schnittstelle
Es wird nur zum Iterieren von Legacy Collection-Klassen verwendet.Wir können es für jede Collection-Klasse verwenden.
Es unterstützt nur den READ-Vorgang.Es unterstützt sowohl READ- als auch DELETE-Operationen.
Es ist kein universeller Cursor.Es ist ein universeller Cursor.
Lange Methodennamen.Einfache und benutzerfreundliche Methodennamen.

3. ListIterator

Es gilt nur für in Listensammlungen implementierte Klassen wie ArrayList, LinkedList usw. Es bietet bidirektionale Iteration. ListIterator muss verwendet werden, wenn wir Elemente von List aufzählen möchten. Dieser Cursor verfügt über mehr Funktionen (Methoden) als der Iterator. Das ListIterator-Objekt kann durch Aufruf erstellt werden listIterator() Methode, die in der List-Schnittstelle vorhanden ist.

Syntax

ListIterator ltr = l.  listIterator  ();>

Notiz: Hier ist l ein beliebiges Listenobjekt, ltr ist vom Typ. ListIterator-Schnittstelle und verweist auf l. Die ListIterator-Schnittstelle erweitert die Iterator-Schnittstelle. Daher sind alle drei Methoden der Iterator-Schnittstelle für ListIterator verfügbar. Darüber hinaus gibt es sechs weitere Methoden.

1. Vorwärtsrichtung

1.1 hasNext(): Gibt true zurück, wenn die Iteration mehr Elemente enthält

public boolean hasNext();>

1.2 next(): Identisch mit der next()-Methode von Iterator. Gibt das nächste Element in der Iteration zurück.

public Object next();>

1.3 nextIndex(): Gibt den nächsten Elementindex oder die Listengröße zurück, wenn sich der Listeniterator am Ende der Liste befindet.

public int nextIndex();>

2. Rückwärtsrichtung

2.1 hasPrevious(): Gibt true zurück, wenn die Iteration beim Rückwärtsdurchlauf mehr Elemente enthält.

public boolean hasPrevious();>

2.2 previous(): Gibt das vorherige Element in der Iteration zurück und kann auslösen NoSuchElementException wenn kein Element mehr vorhanden ist.

public Object previous();>

2.3 previousIndex(): Gibt den vorherigen Elementindex oder -1 zurück, wenn der Listeniterator am Anfang der Liste steht.

Array in Java sortiert
public int previousIndex();>

3. Andere Methoden

3.1 entfernen(): Identisch mit der Methode „remove()“ von Iterator. Entfernt das nächste Element in der Iteration.

awt Java
public void remove();>

3.2 set(Objekt obj): Ersetzt das letzte von next() oder previous() zurückgegebene Element durch das angegebene Element.

public void set(Object obj);>

3.3 add(Objekt obj): Fügt das angegebene Element an der Position vor dem Element, das von next() zurückgegeben würde, in die Liste ein.

public void add(Object obj);>

Ganz klar, die drei Methoden, die ListIterator erbt von Iterator ( hasNext() , nächste() , Und entfernen() ) machen in beiden Schnittstellen genau das Gleiche. Der hasPrevious() und die vorherigen Operationen sind genaue Analogien von hasNext() Und nächste() . Die ersteren Operationen beziehen sich auf das Element vor dem (impliziten) Cursor, während sich die letzteren auf das Element nach dem Cursor beziehen. Der vorherige Vorgang bewegt den Cursor nach hinten, während der nächste ihn vorwärts bewegt.

ListIterator hat kein aktuelles Element; seine Cursorposition liegt immer zwischen dem Element, das bei einem Aufruf von zurückgegeben würde vorherige() und das Element, das durch einen Aufruf von zurückgegeben würde nächste().

1. set() Die Methode kann 4 Ausnahmen auslösen.

  • UnsupportedOperationException: wenn die Set-Operation von diesem Listeniterator nicht unterstützt wird
  • ClassCastException: Wenn die Klasse des angegebenen Elements verhindert, dass es dieser Liste hinzugefügt wird
  • IllegalArgumentException: Wenn ein Aspekt des angegebenen Elements verhindert, dass es dieser Liste hinzugefügt wird
  • Illegale staatliche Ausnahme: Wenn weder „next“ noch „ previous“ aufgerufen wurden oder „remove“ oder „add“ nach dem letzten Aufruf von „next“ oder „ previous“ aufgerufen wurden

2. add() Methode kann 3 Ausnahmen auslösen.

  • UnsupportedOperationException: Wenn die Add-Methode von diesem Listeniterator nicht unterstützt wird
  • ClassCastException: Wenn die Klasse des angegebenen Elements verhindert, dass es dieser Liste hinzugefügt wird
  • IllegalArgumentException: Wenn ein Aspekt dieses Elements verhindert, dass es zu dieser Liste hinzugefügt wird

Beispiel

Java
// Java program to demonstrate ListIterator // Importing ArrayList and List iterator classes // from java.util package import java.util.ArrayList; import java.util.ListIterator; // Main class public class Test { // Main driver method public static void main(String[] args) { // Creating an object of ArrayList class ArrayList al = new ArrayList(); // Iterating over Arraylist object for (int i = 0; i < 10; i++) // Adding elements to the Arraylist object al.add(i); // Print and display all elements inside object // created above System.out.println(al); // At beginning ltr(cursor) will point to // index just before the first element in al ListIterator ltr = al.listIterator(); // Checking the next element availability while (ltr.hasNext()) { // Moving cursor to next element int i = (Integer)ltr.next(); // Getting even elements one by one System.out.print(i + ' '); // Changing even numbers to odd and // adding modified number again in // iterator if (i % 2 == 0) { // Change to odd i++; // Set method to change value ltr.set(i); // To add ltr.add(i); } } // Print and display statements System.out.println(); System.out.println(al); } }>

Ausgabe
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 0 1 2 3 4 5 6 7 8 9 [1, 1, 1, 3, 3, 3, 5, 5, 5, 7, 7, 7, 9, 9, 9]>

Notiz: Ebenso gibt es bestimmte Einschränkungen bei ListIterator . Es handelt sich um den leistungsstärksten Iterator, der jedoch nur für in der Liste implementierte Klassen anwendbar ist und daher kein universeller Iterator ist.

Wichtige Punkte

  1. Bitte beachten Sie, dass zunächst jede Iteratorreferenz auf den Index direkt vor dem Index des ersten Elements in einer Sammlung verweist.
  2. Wir erstellen keine Objekte von Enumeration, Iterator, ListIterator, da es sich um Schnittstellen handelt. Wir verwenden Methoden wie elements(), iterator(), listIterator(), um Objekte zu erstellen. Diese Methoden sind anonym Innere Klasse das die jeweiligen Schnittstellen erweitert und dieses Klassenobjekt zurückgibt.

Notiz: Der $ Das Symbol im Referenzklassennamen ist ein Beweis dafür, dass das Konzept innerer Klassen verwendet wird und diese Klassenobjekte erstellt werden.

Dies kann durch den folgenden Code überprüft werden. Weitere Informationen zur inneren Klasse finden Sie unter

Java
// Java program to demonstrate iterators references // Importing required classes from java.util package import java.util.Enumeration; import java.util.Iterator; import java.util.ListIterator; import java.util.Vector; // Main class public class GFG { // Main driver method public static void main(String[] args) { // Creating an object of Vector class Vector v = new Vector(); // Creating three iterators Enumeration e = v.elements(); Iterator itr = v.iterator(); ListIterator ltr = v.listIterator(); // Print class names of iterators // using getClass() and getName() methods System.out.println(e.getClass().getName()); System.out.println(itr.getClass().getName()); System.out.println(ltr.getClass().getName()); } }>

Ausgabe
java.util.Vector java.util.Vector$Itr java.util.Vector$ListItr>

Erläuterung

In Java ist ein Iterator eine Schnittstelle, die verwendet wird, um eine Sammlung von Objekten einzeln zu durchlaufen. Es wird verwendet, um jede sammlungsbasierte Datenstruktur zu durchlaufen, einschließlich Arrays, Listen, Mengen und Karten.

Ein Iterator verfügt über drei Hauptmethoden, die zum Durchlaufen der Sammlung verwendet werden:

  • hasNext() – Diese Methode prüft, ob es in der Sammlung ein weiteres Element gibt, über das iteriert werden kann.
  • next() – Diese Methode gibt das nächste Element in der Sammlung zurück.
  • remove() – Diese Methode entfernt das aktuelle Element aus der Sammlung.

Die Iterator-Schnittstelle ist Teil des Java Collection Framework und wird von den Klassen implementiert, die die verschiedenen Arten von Sammlungen darstellen.

Programm

Java
import java.util.ArrayList; import java.util.Iterator; public class IteratorExample { public static void main(String[] args) { ArrayListNamen = neue ArrayList(); Namen.add('Alice'); Namen.add('Bob'); Namen.add('Charlie'); Namen.add('David'); // Einen Iterator für den Namenslisten-Iterator erstelleniterator = Namen.iterator(); // Mit dem Iterator über die Namensliste iterieren while (iterator.hasNext()) { String name = iterator.next(); System.out.println(name); } } }>

Ausgabe
Alice Bob Charlie David>

In diesem Beispiel haben wir eine ArrayList mit Zeichenfolgen erstellt und ihr vier Namen hinzugefügt. Anschließend haben wir mit der Methode iterator() der Klasse ArrayList einen Iterator für die Liste erstellt. Wir haben die Methode hasNext() verwendet, um zu überprüfen, ob es weitere Elemente in der Liste gibt, über die iteriert werden muss, und die Methode next(), um das nächste Element in der Liste abzurufen. Wir haben jedes Element mit der Methode System.out.println() gedruckt.

Die Verwendung eines Iterators zum Durchlaufen einer Sammlung ist eine bequeme und effiziente Möglichkeit, die Sammlung zu durchlaufen, da sie es ermöglicht, über die Sammlung zu iterieren, ohne die interne Struktur der Sammlung zu kennen. Es ermöglicht auch das Entfernen von Elementen aus der Sammlung, während darüber iteriert wird.

Vorteile von Iterator in Java:

  • Der Iterator ist eine einfache und benutzerfreundliche Schnittstelle, die es uns ermöglicht, eine Sammlung zu durchlaufen, ohne die zugrunde liegende Implementierung offenzulegen.
  • Der Iterator ist eine effiziente Möglichkeit, eine Sammlung zu durchlaufen, insbesondere wenn wir über große Datenmengen verfügen.
  • Der Iterator bietet eine sichere Möglichkeit, Elemente während der Iteration aus einer Sammlung zu entfernen, ohne gleichzeitige Änderungsausnahmen zu verursachen.
  • Die Iterator-Schnittstelle wird von allen Sammlungsklassen in Java implementiert, sodass wir denselben Code verwenden können, um über verschiedene Arten von Sammlungen zu iterieren.

Nachteile von Iterator in Java:

Die Verwendung von Iterator in Java weist bestimmte Nachteile auf, wie unten erwähnt:

  • Der Iterator ist eine unidirektionale Schnittstelle, was bedeutet, dass wir uns nur durch eine Sammlung vorwärts bewegen können. Wir können nicht rückwärts gehen oder zu einem bestimmten Element springen.
  • Der Iterator ist nicht threadsicher, daher können wir ihn nicht zum Durchlaufen einer Sammlung in einer Multithread-Umgebung ohne ordnungsgemäße Synchronisierung verwenden.
  • Der Iterator bietet außer dem Entfernen von Elementen keinen Mechanismus zum Ändern von Elementen während der Iteration über eine Sammlung. Wenn wir Elemente ändern müssen, müssen wir andere Schnittstellen wie ListIterator oder eine einfache for-Schleife verwenden.