Différence entre l'énumération Java et l'itérateur


Réponses:


142

En regardant la spécification de l'API Java pour l' Iteratorinterface, il y a une explication des différences entre Enumeration:

Les itérateurs diffèrent des énumérations de deux manières:

  • Les itérateurs permettent à l'appelant de supprimer des éléments de la collection sous-jacente pendant l'itération avec une sémantique bien définie.
  • Les noms de méthodes ont été améliorés.

La ligne du bas est, à la fois Enumerationet Iteratordonnera des éléments successifs, mais Iteratorest améliorée de telle sorte que les noms de méthode sont plus courts et ont une removeméthode supplémentaire . Voici une comparaison côte à côte:

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

Comme mentionné également dans les spécifications de l'API Java, pour les programmes plus récents, Iteratoril faut préférer Enumeration, car «Iterator remplace l'énumération dans le cadre des collections Java». (D'après les Iteratorspécifications.)


9
Je pense qu'il manque un peu d'explication dans cette réponse concernant la concurrence.
Maarten Bodewes

@Paul_Draper: Les modifications ne doivent pas ajouter une nouvelle signification au message, c'est à cela que servent les commentaires.
Emil

2
@coobird Êtes-vous sûr que "les énumérations sont généralement plus rapides"? puisque Enumeration a "synchronizing block of code inside the nextElement ()" Et nous n'avons pas de synchronisation au niveau des itérateurs, ce qui cause ConcurrentModificationException rit ?? Les itérateurs sont généralement plus rapides et les énumérations sont un peu plus sûres. ??
Kanagavelu Sugumar

@KanagaveluSugumar Merci de l'avoir signalé. (Je n'ai pas remarqué que la discussion supplémentaire avait été ajoutée à cette réponse.) J'ai annulé la modification, car elle n'était pas tout à fait exacte.
coobird

Je pense qu'il vaut la peine de souligner que remove () est une méthode facultative sur l'interface Iterator et que de nombreuses classes d'implémentation ne l'implémentent pas.
Kutzi le

35

Les itérateurs sont rapides . c'est-à-dire que lorsqu'un thread modifie la collection par des opérations d'ajout / de suppression, tandis qu'un autre thread le traverse à travers un itérateur utilisant la hasNext() or next()méthode, l'itérateur échoue rapidement en lançant ConcurrentModificationException. Le comportement rapide des itérateurs ne peut être utilisé que pour détecter des bogues. Les énumérations retournées par les méthodes de classes telles que Hashtable, Vector ne sont pas rapides, ce qui est obtenu en synchronisant le bloc de code à l'intérieur de la nextElement()méthode qui verrouille l'objet Vector actuel, ce qui coûte beaucoup de temps.


5
Seulement en partie vrai: ce comportement n'est pas défini dans l'interface, il dépend de l'implémentation de l'itérateur. Il est vrai que les «anciennes» implémentations de collection dans java.util (HashSet, ArrayList etc.) présentent ce comportement. Cependant, les nouvelles collections «simultanées» ne lèveront jamais d'exception ConcurrentModificationException, elles traverseront la collection à partir du moment de la création de l'itérateur. D'autres implémentations peuvent montrer un comportement encore différent.
Kutzi

1
Il convient également de souligner: "Notez que le comportement à échec rapide ne peut pas être garanti car il est, d'une manière générale, impossible de faire des garanties fermes en présence de modifications concurrentes non synchronisées. Les opérations à échec rapide lancent l'exception ConcurrentModificationException au mieux. Par conséquent , il serait erroné d'écrire un programme qui dépendait de cette exception pour son exactitude: ConcurrentModificationException ne doit être utilisé que pour détecter les bogues. " docs.oracle.com/javase/7/docs/api/java/util/…
Kutzi

11

"Officiellement", ils sont censés être similaires avec l'interface de l'itérateur prenant en charge des opérations supplémentaires (par exemple, la suppression). Généralement, la tendance est d'utiliser des itérateurs.

Voici des javadocs de l'interface d'énumération :

REMARQUE: la fonctionnalité de cette interface est dupliquée par l'interface Iterator. En outre, Iterator ajoute une opération de suppression facultative et a des noms de méthode plus courts. Les nouvelles implémentations devraient envisager d'utiliser Iterator de préférence à Enumeration.


6

Un fait simple mais non mentionné dans les réponses précédentes est qu'il Iterator<T>est utilisé avec Iterable<T>pour servir à interpréter la for(_type_ element:collection){...}structure.


5

Il y a trois différences fondamentales dans l'énumération et l'itérateur

Enumération
1. il est utilisé uniquement pour la classe de latence (par exemple Vector)

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

2. L'opération de lecture peut être effectuée, nous ne pouvons pas supprimer l'élément.
3. Deux méthodes sont disponibles

  • public booléen hasNextElement ();
  • objet public nextElement ();

Itérateur

  1. il s'applique à toutes les collections

    Iterator itr = c.iterator();  
    where c is any `Collection` class
  2. L'opération de lecture et de suppression peut être effectuée

  3. Trois méthodes sont disponibles

    • public booléen hasNext ();
    • objet public suivant ();
    • public void remove ();

Limitation dans les deux

  • Avancer uniquement vers l'avant
  • Il n'y a aucune méthode pour Add objectetReplace object

2

Si vous écrivez votre propre classe de collection et que vous étendez l'une des classes existantes ou implémentez l'une des interfaces du framework Collections, vous n'avez fondamentalement pas d'autre choix que d'utiliser Iterator.

Si, pour une raison quelconque (à laquelle je ne pense pas), vous créez une classe de collection personnalisée qui ne se rapporte pas à java.util.Collection ou java.util.Map de quelque manière que ce soit, vous devez toujours implémenter Iterable afin que les gens puissent utiliser votre classe en boucle for.


2

La principale différence est que l'énumération n'expose pas la méthode remove (). De plus, Iterator ne permet pas une navigation et une modification simultanées sur un objet sous-jacent. Ils ont un contrôle pour voir s'il y a des modifications simultanées ou plus, et nécessitent donc plus de traitement. Les performances d'énumération sont donc pratiquement 50% plus rapides que celles d'itérateur. Si nous n'avons besoin que de la navigation en ignorant une telle synchronisation, utilisez simplement Enumeration.


Il est vrai que Enumeration n'expose "pas" la méthode remove () - mais il ne fait pas non plus attention à l'invocation de l'api remove () de Collection. Par exemple, le code suivant imprimera simplement: AAA, CCC, EEE. -------------------------------------------------- --- Vecteur <String> v = nouveau vecteur <String> (6); v.add ("AAA"); v.add ("BBB"); v.add ("CCC"); v.add ("DDD"); v.add ("EEE"); v.add ("FFF"); Énumération <String> en = v.elements (); while (en.hasMoreElements ()) String value = (String) en.nextElement (); System.out.println (valeur); v.remove (valeur);
javauser71

1

1) La principale différence entre Iterator et Enumeration est la suppression de l'élément lors de la traversée de la collection. Iterator peut supprimer l'élément pendant le parcours de la collection car il dispose de la méthode remove (). L'énumération n'a pas de méthode remove ().

2) L'énumération est de nature à sécurité intégrée. Il ne lève pas ConcurrentModificationException si Collection est modifiée pendant la traversée. Iterator est par nature ultra-rapide. Il lève une exception ConcurrentModificationException si une collection est modifiée lors d'une itération autre que sa propre méthode remove ().

3) L'énumération est une interface héritée qui est utilisée pour parcourir Vector, Hashtable. Iterator n'est pas une interface héritée. Iterator peut être utilisé pour le parcours de HashMap, LinkedList, ArrayList, HashSet, TreeMap, TreeSet.


0

L'énumération ne peut être utilisée que pour la classe héritée (Vector, Stack ...), tandis que Iterator peut être utilisé pour tous.


-1

L'itérateur et l'énumération sont utilisés pour récupérer les données, la différence est que l'énumération ne peut être utilisée que pour les classes héritées, c'est-à-dire vecteur / pile, tandis que les itérateurs peuvent être utilisés pour le reste. L'énumération peut également être utilisée pour l'ensemble de clés dans les cartes.


Où avez-vous vu que vous pouvez utiliser Enumeration pour les ensembles de clés de Map ??
Kutzi
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.