Differenza tra Java Enumeration e Iterator


Risposte:


142

Guardando la specifica dell'API Java per l' Iteratorinterfaccia, c'è una spiegazione delle differenze tra Enumeration:

Gli iteratori differiscono dalle enumerazioni in due modi:

  • Gli iteratori consentono al chiamante di rimuovere elementi dalla raccolta sottostante durante l'iterazione con semantica ben definita.
  • I nomi dei metodi sono stati migliorati.

La linea di fondo è, sia Enumeratione Iteratorfornirà elementi successivi, ma Iteratorè migliorata in modo tale che i nomi dei metodi siano più brevi e abbia un removemetodo aggiuntivo . Ecco un confronto fianco a fianco:

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

Come menzionato anche nelle specifiche dell'API Java, per i programmi più recenti, Iteratordovrebbe essere preferito rispetto Enumerationa "Iterator prende il posto dell'enumerazione nel framework delle raccolte Java". (Dalle Iteratorspecifiche.)


9
Penso che manchi un po 'di spiegazione in questa risposta per quanto riguarda la concorrenza.
Maarten Bodewes

@Paul_Draper: le modifiche non dovrebbero aggiungere un nuovo significato al post, questo è ciò a cui servono i commenti.
Emil

2
@coobird Sei sicuro che "le enumerazioni sono generalmente più veloci"? poiché Enumeration ha "blocco di codice di sincronizzazione all'interno di nextElement ()" e non abbiamo sincronizzazione su iteratori che causa ConcurrentModificationException rit ?? Chiamiamo gli iteratori in genere più veloci e le enumerazioni sono un po 'più sicure. ??
Kanagavelu Sugumar

@KanagaveluSugumar Grazie per averlo sottolineato. (Non ho notato che la discussione aggiuntiva è stata aggiunta a questa risposta.) Ho annullato la modifica, poiché non era del tutto accurata.
coobird

Penso che valga la pena sottolineare che remove () è un metodo opzionale sull'interfaccia di Iterator e molte classi di implementazione non lo implementano.
Kutzi

35

Gli iteratori sono rapidi . cioè quando un thread cambia la collezione aggiungendo / rimuovi operazioni, mentre un altro thread la sta attraversando attraverso un iteratore usando il hasNext() or next()metodo, l'iteratore fallisce rapidamente lanciando ConcurrentModificationException. Il comportamento veloce degli iteratori può essere utilizzato solo per rilevare bug. Le Enumerazioni restituite dai metodi di classi come Hashtable, Vector non sono veloci che si ottengono sincronizzando il blocco di codice all'interno del nextElement()metodo che blocca l'oggetto Vector corrente che costa molto tempo.


5
Solo in parte vero: questo comportamento non è definito nell'interfaccia, spetta all'implementazione di Iterator. È vero che le "vecchie" implementazioni della raccolta in java.util (HashSet, ArrayList ecc.) Presentano questo comportamento. Tuttavia, le raccolte "simultanee" più recenti non genereranno mai un'eccezione ConcurrentModificationException, ma attraverseranno la raccolta al momento della creazione dell'iteratore. Altre implementazioni possono mostrare un comportamento ancora diverso.
Kutzi

1
Vale anche la pena sottolineare: "Si noti che il comportamento fail-fast non può essere garantito in quanto, in generale, è impossibile fornire garanzie rigide in presenza di modifiche simultanee non sincronizzate. Le operazioni fail-fast generano ConcurrentModificationException su una base del massimo sforzo. Pertanto , sarebbe sbagliato scrivere un programma che dipende da questa eccezione per la sua correttezza: ConcurrentModificationException dovrebbe essere usato solo per rilevare bug. " docs.oracle.com/javase/7/docs/api/java/util/…
Kutzi

11

"Ufficialmente", dovrebbero essere simili con l'interfaccia dell'iteratore che supporta operazioni extra (es. Rimozione). In generale, la tendenza è quella di utilizzare gli iteratori.

Ecco dall'interfaccia di enumerazione javadocs :

NOTA: la funzionalità di questa interfaccia è duplicata dall'interfaccia Iterator. Inoltre, Iterator aggiunge un'operazione di rimozione facoltativa e ha nomi di metodo più brevi. Le nuove implementazioni dovrebbero prendere in considerazione l'utilizzo di Iterator rispetto all'enumerazione.


6

Un fatto semplice ma non menzionato nelle risposte precedenti è che Iterator<T>viene utilizzato Iterable<T>per servire nell'interpretazione della for(_type_ element:collection){...}struttura.


5

Esistono tre differenze fondamentali in Enumeration e Iterator

Enumerazione
1. è utilizzato solo per la classe di lagacy (es. Vector)

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

2. L'operazione di lettura può essere eseguita, non possiamo rimuovere l'elemento.
3. Sono disponibili due metodi

  • public boolean hasNextElement ();
  • public Object nextElement ();

Iterator

  1. è applicabile a tutta la raccolta

    Iterator itr = c.iterator();  
    where c is any `Collection` class
  2. È possibile eseguire l'operazione di lettura e rimozione

  3. Sono disponibili tre metodi

    • public boolean hasNext ();
    • public Object next ();
    • public void remove ();

Limitazione in entrambi

  • Spostarsi solo in avanti
  • Non esistono metodi per Add objecteReplace object

2

Se stai scrivendo la tua classe di raccolta e stai estendendo una qualsiasi delle classi esistenti o implementando una qualsiasi delle interfacce del framework delle raccolte, in pratica non hai altra scelta che usare Iterator.

Se per qualche motivo (a cui non riesco a pensare) stai creando una classe di raccolta personalizzata che non è correlata a java.util.Collection o java.util.Map in alcun modo, dovresti comunque implementare Iterable in modo che le persone possano usare la tua classe in cicli for.


2

La differenza principale è che l'enumerazione non espone il metodo remove (). Inoltre, Iterator non consente la navigazione e la modifica contemporaneamente su un oggetto sottostante. Hanno un controllo per vedere se ci sono modifiche simultanee o giù di lì, e quindi richiede più elaborazione. Quindi le prestazioni di Enumeration sono praticamente il 50% più veloci di Iterator. Se è necessaria solo la navigazione ignorando tale sincronizzazione, è sufficiente utilizzare Enumerazione.


È vero che Enumeration "non" espone il metodo remove (), ma non presta attenzione al richiamo dell'api remove () di Collection. Ad esempio, il codice seguente verrà stampato solo: AAA, CCC, EEE. -------------------------------------------------- --- Vector <String> v = new Vector <String> (6); v.add ( "AAA"); v.add ( "BBB"); v.add ( "CCC"); v.add ( "DDD"); v.add ( "AEE"); v.add ( "FFF"); Enumerazione <String> en = v.elements (); while (en.hasMoreElements ()) String value = (String) en.nextElement (); System.out.println (valore); v.remove (valore);
javauser71

1

1) La principale differenza tra Iterator ed Enumeration è la rimozione dell'elemento durante l'attraversamento della raccolta. Iterator può rimuovere l'elemento durante l'attraversamento della raccolta poiché ha il metodo remove (). L'enumerazione non ha il metodo remove ().

2) L'enumerazione è di natura sicura. Non genera ConcurrentModificationException se Collection viene modificata durante l'attraversamento. Iterator è di natura rapida. Genera ConcurrentModificationException se una Collection viene modificata durante l'iterazione in modo diverso dal proprio metodo remove ().

3) Enumeration è un'interfaccia legacy che viene utilizzata per attraversare Vector, Hashtable. Iterator non è un'interfaccia legacy. Iterator può essere utilizzato per l'attraversamento di HashMap, LinkedList, ArrayList, HashSet, TreeMap, TreeSet.


0

L'enumerazione può essere utilizzata solo per la classe legacy (Vector, Stack ...), mentre Iterator può essere utilizzato per tutti.


-1

Sia l'iteratore che l'enumerazione vengono utilizzati per recuperare i dati, la differenza è che l'enumerazione può essere utilizzata solo per le classi legacy, ad esempio vettore / stack, mentre gli iteratori possono essere utilizzati per il resto. L'enumerazione può essere utilizzata anche per la chiave impostata nelle mappe.


Dove hai visto che puoi usare Enumeration per i set di chiavi di Map ??
Kutzi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.