2009-06-04 7 views
102

Jaka jest dokładna różnica między tymi dwoma interfejsami? Czy Enumeration ma korzyści z używania Iterator? Gdyby ktokolwiek mógł się rozwinąć, należałoby zapoznać się z artykułem referencyjnym.Różnica między wyliczaniem Java a Iteratorem

+3

Użyłem wyszukiwarki Google, a pierwszym rezultatem była interesująca dyskusja w JavaRanch na temat [Wyliczenie kontra Iterator] (http://www.coderanch.com/t/202139/Performance/java/Enumeration-vs-Iterator) –

Odpowiedz

124

Patrząc na API Specification Java dla interfejsu Iterator, jest wyjaśnienie różnic między Enumeration:

Iteratory różnią się od wyliczeń na dwa sposoby:

  • Iteratory pozwolić rozmówcy w celu usunięcia elementów z podstawowej kolekcji podczas iteracji z dobrze zdefiniowaną semantyką.
  • Poprawiono nazwy metod.

Najważniejsze jest to, że oba Enumeration i Iterator daje kolejne elementy, ale Iterator poprawia się w taki sposób, nazwy metod są krótsze i ma dodatkową metodę remove. Oto porównanie side-by-side:

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

jak wspomniano również w API specyfikacji Java dla nowszych programów Iterator powinny być preferowane nad Enumeration, jak „Iterator ma miejsce Enumeration w zbiorach ramach Java . " (Z specyfikacji Iterator.)

+6

Sądzę, że brakuje pewnej ilości wyjaśnień w tej odpowiedzi dotyczącej współbieżności. –

+0

@Paul_Draper: Zmiany nie powinny dodawać nowego znaczenia do posta, do czego służą komentarze. – Emil

+2

@coobird Czy na pewno "Wyliczenia są zazwyczaj szybsze"? ponieważ Enumeration ma "synchronizujący blok kodu wewnątrz nextElement()" I nie mamy synchronizacji w Iteratorach, co powoduje rytualność ConcurrentModificationException? Czy nazywamy Iteratory są zazwyczaj szybsze, a wyliczenia są trochę bezpieczniejsze. ?? –

11

"Oficjalnie", mają być podobne z interfejsem iteratora obsługującym dodatkowe operacje (np. Usuwanie). Zasadniczo tendencją jest stosowanie iteratorów.

Oto od the enumeration interface javadocs:

UWAGA: Funkcjonalność tego interfejsu jest powielany przez interfejs Iterator. Ponadto, Iterator dodaje opcjonalną operację usunięcia i ma krótsze nazwy metod. Nowe implementacje powinny rozważyć użycie Iteratora w preferencjach do wyliczenia.

2

Jeśli piszesz własną klasę kolekcji i rozszerzasz którąkolwiek z istniejących klas lub implementujesz któryś z interfejsów do Kolekcji kolekcji, w zasadzie nie masz innego wyjścia, jak używać Iteratora.

Jeśli z jakiegoś powodu (że nie mogę myśleć) tworzysz klasę zwyczaj zbierania, które nie odnoszą się do java.util.Collection lub java.util.Map w jakikolwiek sposób, należy nadal implementuj Iterable, aby ludzie mogli używać twojej klasy w pętlach.

2

Podstawową różnicą jest wyliczenie, które nie udostępnia metody remove(). Co więcej, Iterator nie pozwala na jednoczesną nawigację i modyfikację obiektu leżącego pod spodem. Mają kontrolę, aby zobaczyć, czy są równoczesne modyfikacje, a więc więcej przetwarzania. Tak więc wydajność wyliczenia jest praktycznie o 50% szybsza od Iteratora. Jeśli potrzebujemy tylko nawigacji ignorującej taką synchronizację, wystarczy użyć wyliczenia.

+0

To prawda, że ​​wyliczenie "nie" ujawnia metodę remove() - ale nie zwraca też uwagi na wywołanie funkcji remove() kolekcji. Na przykład poniższy kod po prostu wydrukuje: AAA, CCC, EEE. ------------------------------------------------ ----- Wektor v = nowy wektor (6); v.add ("AAA"); v.add ("BBB"); v.add ("CCC"); v.add ("DDD"); v.add ("EEE"); v.add ("FFF"); Enumeracja pl = v.elements(); while (en.hasMoreElements()) String value = (String) en.nextElement(); System.out.println (wartość); v.remove (wartość); – javauser71

-1

Zarówno iterator, jak i wyliczenie są używane do pobierania danych. Różnica polega na tym, że wyliczanie może być używane tylko w starszych klasach, np. Wektor/stos, podczas gdy iteratory mogą być używane do dalszej obróbki. Wyliczenie może być również użyte dla zestawu kluczy w mapach.

+0

Gdzie widziałeś, że możesz używać wyliczenia dla kluczowych zestawów mapy? – Kutzi

31

Iteratory są fail-szybko. tj. gdy jeden wątek zmienia kolekcję przez operacje dodawania/usuwania, podczas gdy inny wątek przechodzi przez iterator za pomocą metody hasNext() or next(), iterator szybko się zawiesza, rzucając ConcurrentModificationException. Szybkie działanie iteratorów może być wykorzystywane tylko do wykrywania błędów. Wyliczenia zwrócone przez metody klas takie jak Hashtable, Vector nie są odporne na awarię, co osiąga się przez zsynchronizowanie bloku kodu wewnątrz metody nextElement(), która blokuje bieżący obiekt Vector, który kosztuje dużo czasu.

+4

Tylko częściowo prawda: to zachowanie nie jest zdefiniowane w interfejsie, to zależy od implementacji Iteratora. To prawda, że ​​"stare" implementacje kolekcji w java.util (HashSet, ArrayList itp.) Wykazują takie zachowanie. Jednak nowsze kolekcje "współbieżne" nigdy nie wyrzucą wyjątku ConcurrentModificationException, będą przechodzić przez kolekcję od momentu utworzenia iteratora. Inne implementacje mogą pokazywać inne zachowanie. – Kutzi

+0

Warto również zwrócić uwagę: "Należy pamiętać, że nie można zagwarantować zachowania odpornego na awarie, ponieważ generalnie niemożliwe jest wykonanie jakichkolwiek twardych gwarancji w przypadku niezsynchronizowanej, współbieżnej modyfikacji. Szybkie działania powodują, że ConcurrentModificationException działa z najwyższą starannością. Dlatego błędem byłoby napisanie programu, który zależałby od tego wyjątku pod względem jego poprawności: ConcurrentModificationException powinien być używany tylko do wykrywania błędów. " http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html – Kutzi

6

Jeden prosty fakt, ale nie wspomniałem w poprzednich odpowiedziach, że Iterator<T> jest używany z Iterable<T> do tłumaczenia interpretacji struktury for(_type_ element:collection){...}.

4

Istnieje podstawowa różnica w trzy Enumeration i Iterator

Wyliczanie
1. jest stosowanie wyłącznie lagacy klasy (np. Vector)

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

2. operacji odczytu można wykonać , nie możemy usunąć elementu.
3. Dwa Metoda są dostępne

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

Iterator

  1. ma ona zastosowanie do wszystkich kolekcji

    Iterator itr = c.iterator(); 
    where c is any `Collection` class 
    
  2. przeczytane i Usuń operację można wykonać

  3. Trzy metody są dostępne

    • public boolean hasNext();
    • obiekt publiczny następny();
    • public void remove();

Limition zarówno

  • poruszać się tylko do przodu w kierunku
  • Nie ma żadnych metod Add object i Replace object
0

Wyliczenie może być używany tylko do spuścizny klasa (wektor, stos ...), podczas gdy Iterator może być używany dla wszystkich.