Unterschied zwischen Java Enumeration und Iterator

120

Was ist der genaue Unterschied zwischen diesen beiden Schnittstellen? Hat EnumerationVorteile gegenüber der Verwendung Iterator? Wenn jemand näher darauf eingehen könnte, wäre ein Referenzartikel willkommen.

Cometta
quelle
3
Früher habe ich eine Google - Suche und das erste Ergebnis war eine interessante Diskussion in JavaRanch über Enumeration vs Iterator
victor hugo

Antworten:

142

In der Java-API-Spezifikation für die IteratorSchnittstelle werden die Unterschiede erklärt zwischen Enumeration:

Iteratoren unterscheiden sich von Aufzählungen in zweierlei Hinsicht:

  • Mit Iteratoren kann der Aufrufer während der Iteration Elemente aus der zugrunde liegenden Sammlung mit genau definierter Semantik entfernen.
  • Methodennamen wurden verbessert.

Das Endergebnis ist beides Enumerationund Iteratorgibt aufeinanderfolgende Elemente, wird jedoch Iteratorso verbessert, dass die Methodennamen kürzer sind und eine zusätzliche removeMethode haben. Hier ist ein Vergleich nebeneinander:

  Enumeration                     Iterator
  ----------------                ----------------
  hasMoreElement()                hasNext()
  nextElement()                   next()
  N/A                             remove()

Wie auch in den Java-API-Spezifikationen erwähnt, sollte für neuere Programme "Iterator ersetzt die Aufzählung im Java-Sammlungsframework" Iteratorvorgezogen werden Enumeration. (Aus den IteratorSpezifikationen.)

Coobird
quelle
9
Ich denke, in dieser Antwort fehlt eine Erklärung bezüglich der Parallelität.
Maarten Bodewes
@Paul_Draper: Änderungen sollten dem Beitrag keine neue Bedeutung verleihen, dafür sind Kommentare gedacht.
Emil
2
@coobird Sind Sie sicher, dass "Aufzählungen normalerweise schneller sind"? da Enumeration "Synchronisieren eines Codeblocks innerhalb des nextElement ()" hat und wir keine Synchronisation bei Iteratoren haben, was ConcurrentModificationException rit verursacht ?? Nennen wir Iteratoren normalerweise schneller und Aufzählungen sind etwas sicherer. ??
Kanagavelu Sugumar
@KanagaveluSugumar Vielen Dank, dass Sie darauf hingewiesen haben. (Ich habe nicht bemerkt, dass die zusätzliche Diskussion zu dieser Antwort hinzugefügt wurde.) Ich habe die Bearbeitung zurückgesetzt, da sie nicht ganz korrekt war.
Coobird
Ich denke, es ist erwähnenswert, dass remove () eine optionale Methode auf der Iterator-Schnittstelle ist und viele implementierende Klassen sie nicht implementieren.
Kutzi
35

Iteratoren sind ausfallsicher . Das heißt, wenn ein Thread die Sammlung durch Hinzufügen / Entfernen ändert, während ein anderer Thread sie mithilfe einer hasNext() or next()Methode durch einen Iterator durchläuft , schlägt der Iterator durch Auslösen schnell fehl ConcurrentModificationException. Das ausfallsichere Verhalten von Iteratoren kann nur zum Erkennen von Fehlern verwendet werden. Die von den Methoden von Klassen wie Hashtable, Vector zurückgegebenen Aufzählungen sind nicht ausfallsicher. Dies wird erreicht, indem der Codeblock innerhalb der nextElement()Methode synchronisiert wird, die das aktuelle Vector-Objekt sperrt, was viel Zeit kostet.

shaILU
quelle
5
Nur teilweise wahr: Dieses Verhalten ist nicht in der Schnittstelle definiert, es liegt an der Implementierung des Iterators. Es ist wahr, dass die 'alten' Auflistungsimplementierungen in java.util (HashSet, ArrayList usw.) dieses Verhalten aufweisen. Die neueren "gleichzeitigen" Sammlungen lösen jedoch niemals eine ConcurrentModificationException aus. Sie durchlaufen die Sammlung zum Zeitpunkt der Erstellung des Iterators. Andere Implementierungen zeigen möglicherweise noch ein anderes Verhalten.
Kutzi
1
Hervorzuheben ist auch: "Beachten Sie, dass ein Fail-Fast-Verhalten nicht garantiert werden kann, da es im Allgemeinen unmöglich ist, bei nicht synchronisierten gleichzeitigen Änderungen harte Garantien zu geben. Fail-Fast-Vorgänge lösen ConcurrentModificationException auf Best-Effort-Basis aus Es wäre falsch, ein Programm zu schreiben, dessen Richtigkeit von dieser Ausnahme abhängt: ConcurrentModificationException sollte nur zum Erkennen von Fehlern verwendet werden. " docs.oracle.com/javase/7/docs/api/java/util/…
Kutzi
11

"Offiziell" sollen sie mit der Iterator-Schnittstelle ähnlich sein, die zusätzliche Operationen unterstützt (z. B. Entfernen). Im Allgemeinen besteht die Tendenz, Iteratoren zu verwenden.

Hier ist von der Aufzählungsschnittstelle javadocs :

HINWEIS: Die Funktionalität dieser Schnittstelle wird von der Iterator-Schnittstelle dupliziert. Darüber hinaus fügt Iterator eine optionale Entfernungsoperation hinzu und verfügt über kürzere Methodennamen. Neue Implementierungen sollten die Verwendung von Iterator anstelle von Enumeration in Betracht ziehen.

Uri
quelle
6

Eine einfache Tatsache, die in früheren Antworten noch nicht erwähnt wurde, ist, dass Iterator<T>sie Iterable<T>zur Interpretation von for(_type_ element:collection){...}Strukturen verwendet wird.

Erdmotor
quelle
5

Es gibt drei grundlegende Unterschiede zwischen Aufzählung und Iterator

Aufzählung
1. Es wird nur für Verzögerungsklassen verwendet (z. B. Vector).

    Enumeration e = v.elements();  
    v is the object of `Vector` class

2. Lesevorgang kann ausgeführt werden, Element kann nicht entfernt werden.
3. Es stehen zwei Methoden zur Verfügung

  • public boolean hasNextElement ();
  • öffentliches Objekt nextElement ();

Iterator

  1. Es gilt für alle Sammlungen

    Iterator itr = c.iterator();  
    where c is any `Collection` class
  2. Lese- und Entfernungsvorgänge können ausgeführt werden

  3. Es stehen drei Methoden zur Verfügung

    • public boolean hasNext ();
    • öffentliches Objekt next ();
    • public void remove ();

Einschränkung in beiden

  • Bewegen Sie sich nur in Vorwärtsrichtung
  • Es gibt keine Methoden für Add objectundReplace object
Vipin Jain
quelle
2

Wenn Sie Ihre eigene Auflistungsklasse schreiben und eine der vorhandenen Klassen erweitern oder eine der Collections-Framework-Schnittstellen implementieren, haben Sie grundsätzlich keine andere Wahl, als Iterator zu verwenden.

Wenn Sie aus irgendeinem Grund (an den ich nicht denken kann) eine benutzerdefinierte Auflistungsklasse erstellen, die sich in keiner Weise auf java.util.Collection oder java.util.Map bezieht, sollten Sie Iterable dennoch implementieren, damit Benutzer es verwenden können Ihre Klasse für Schleifen.

Licky Lindsay
quelle
2

Der Hauptunterschied besteht darin, dass die Aufzählung die Methode remove () nicht verfügbar macht. Darüber hinaus erlaubt Iterator keine gleichzeitige Navigation und Änderung eines zugrunde liegenden Objekts. Sie können steuern, ob gleichzeitig Änderungen vorgenommen werden, und benötigen daher mehr Verarbeitung. Die Leistung von Enumeration ist also praktisch 50% schneller als die von Iterator. Wenn wir nur eine Navigation benötigen, die eine solche Synchronisation ignoriert, verwenden Sie einfach Enumeration.

bnguyen82
quelle
Es ist wahr, dass Enumeration die remove () -Methode "nicht" verfügbar macht - aber es wird auch nicht auf den Aufruf der remove () - API von Collection geachtet. Der folgende Code wird beispielsweise nur gedruckt: AAA, CCC, EEE. -------------------------------------------------- --- Vektor <String> v = neuer Vektor <String> (6); v.add ("AAA"); v.add ("BBB"); v.add ("CCC"); v.add ("DDD"); v.add ("EEE"); v.add ("FFF"); Aufzählung <String> en = v.elements (); while (en.hasMoreElements ()) String value = (String) en.nextElement (); System.out.println (Wert); v.remove (Wert);
javauser71
1

1) Der Hauptunterschied zwischen Iterator und Aufzählung besteht darin, das Element beim Durchlaufen der Sammlung zu entfernen. Iterator kann das Element während des Durchlaufs der Sammlung entfernen, da es die Methode remove () hat. Die Aufzählung hat keine remove () -Methode.

2) Die Aufzählung ist ausfallsicher. Es wird keine ConcurrentModificationException ausgelöst, wenn die Sammlung während des Durchlaufs geändert wird. Iterator ist von Natur aus ausfallsicher. Es löst eine ConcurrentModificationException aus, wenn eine Sammlung geändert wird, während eine andere als die eigene remove () -Methode iteriert wird.

3) Enumeration ist eine Legacy-Schnittstelle, die zum Durchlaufen von Vector Hashtable verwendet wird. Iterator ist keine Legacy-Schnittstelle. Iterator kann zum Durchlaufen von HashMap, LinkedList, ArrayList, HashSet, TreeMap, TreeSet verwendet werden.

Dhirendra Gautam
quelle
0

Die Aufzählung kann nur für die Legacy-Klasse (Vector, Stack ...) verwendet werden, während Iterator für alle verwendet werden kann.

Jay Sheth
quelle
-1

Sowohl der Iterator als auch die Aufzählung werden zum Abrufen der Daten verwendet. Der Unterschied besteht darin, dass die Aufzählung nur für ältere Klassen, dh Vektor / Stapel, verwendet werden kann, während Iteratoren für den Rest verwendet werden können. Die Aufzählung kann auch für den in Karten festgelegten Schlüsselsatz verwendet werden.

Pavan Kumar
quelle
Wo haben Sie gesehen, dass Sie Enumeration für Schlüsselsätze von Map verwenden können?
Kutzi