Разница между перечислением Java и итератором

Какова точная разница между этими двумя интерфейсами? Имеет ли Enumeration преимущества перед использованием Iterator? Если кто-то может уточнить, справочная статья будет оценена.


person cometta    schedule 04.06.2009    source источник
comment
Я воспользовался поиском в Google, и первым результатом было интересное обсуждение в JavaRanch о Перечисление и итератор   -  person victor hugo    schedule 04.06.2009


Ответы (10)


Просмотр спецификации Java API для Iterator интерфейс, есть объяснение различий между Enumeration:

Итераторы отличаются от перечислений двумя способами:

  • Итераторы позволяют вызывающему объекту удалять элементы из базовой коллекции во время итерации с четко определенной семантикой.
  • Имена методов были улучшены.

Суть в том, что и Enumeration, и Iterator будут давать последовательные элементы, но Iterator улучшили имена методов, сократив многословие, и у него есть дополнительный метод remove. Вот параллельное сравнение:

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

Как также упоминается в Спецификациях Java API, для новых программ Iterator следует предпочесть Enumeration, поскольку Iterator занимает место Enumeration в структуре коллекций Java. (Из спецификаций Iterator.)

person coobird    schedule 04.06.2009
comment
Я думаю, что в этом ответе отсутствует некоторое объяснение относительно параллелизма. - person Maarten Bodewes; 24.07.2012
comment
@Paul_Draper: Правки не должны добавлять новый смысл сообщению, для этого и нужны комментарии. - person Emil; 11.11.2012
comment
@coobird Вы уверены, что перечисления обычно быстрее? поскольку Enumeration имеет синхронизирующий блок кода внутри nextElement(), и у нас нет синхронизации в итераторах, что вызывает ConcurrentModificationException rit ?? Вызываем ли мы Iterators, как правило, быстрее, а Enumerations немного безопаснее. ?? - person Kanagavelu Sugumar; 04.03.2013
comment
@KanagaveluSugumar Спасибо, что указали на это. (Я не заметил, что к этому ответу было добавлено дополнительное обсуждение.) Я отменил редактирование, так как оно было не совсем точным. - person coobird; 05.03.2013
comment
Я думаю, стоит отметить, что remove() — это необязательный метод интерфейса Iterator, и довольно много классов реализации не реализуют его. - person Kutzi; 27.07.2014
comment
Имена методов были улучшены. - Спасибо за честность ;) - person Deqing; 02.10.2014
comment
пожалуйста, добавьте отказоустойчивое объяснение и к этому ответу! - person radistao; 18.01.2016
comment
@coobird просто интересно, почему в перечислении нет метода удаления? - person rocky; 10.01.2018

Итераторы отказоустойчивы . то есть, когда один поток изменяет коллекцию с помощью операций добавления/удаления, в то время как другой поток проходит через итератор, используя метод hasNext() or next(), итератор быстро выходит из строя, выдавая ConcurrentModificationException. Безотказное поведение итераторов можно использовать только для обнаружения ошибок. Перечисления, возвращаемые методами таких классов, как Hashtable, Vector, не являются отказоустойчивыми, что достигается за счет синхронизации блока кода внутри метода nextElement(), который блокирует текущий объект Vector, что требует много времени.

person shaILU    schedule 26.10.2012
comment
Верно лишь отчасти: это поведение не определено в интерфейсе, оно зависит от реализации Итератора. Это правда, что «старые» реализации коллекций в java.util (HashSet, ArrayList и т. д.) демонстрируют такое поведение. Однако более новые «параллельные» коллекции никогда не вызовут исключение ConcurrentModificationException, они будут проходить коллекцию с момента создания итератора. Другие реализации могут показывать другое поведение. - person Kutzi; 27.07.2014
comment
Также стоит отметить: обратите внимание, что отказоустойчивое поведение не может быть гарантировано, поскольку, вообще говоря, невозможно дать какие-либо жесткие гарантии при наличии несинхронизированной параллельной модификации. Быстрые отказоустойчивые операции вызывают исключение ConcurrentModificationException в максимально возможной степени. Поэтому было бы неправильно писать программу, корректность которой зависела бы от этого исключения: ConcurrentModificationException следует использовать только для обнаружения ошибок. docs.oracle.com/javase/7/docs/ API/java/утилита/ - person Kutzi; 27.07.2014

«Официально» они должны быть похожи на интерфейс итератора, поддерживающий дополнительные операции (например, удаление). Как правило, тенденция заключается в использовании итераторов.

Вот из интерфейса перечисления javadocs:

ПРИМЕЧАНИЕ. Функции этого интерфейса дублируются интерфейсом Iterator. Кроме того, Iterator добавляет необязательную операцию удаления и имеет более короткие имена методов. В новых реализациях следует рассмотреть возможность использования Iterator вместо Enumeration.

person Uri    schedule 04.06.2009

Один простой факт, но не упомянутый в предыдущих ответах, заключается в том, что Iterator<T> используется с Iterable<T> для интерпретации структуры for(_type_ element:collection){...}.

person Earth Engine    schedule 25.02.2013

Существует три основных различия в перечислении и итераторе.

Перечисление
1. используется только для устаревшего класса (например, Vector)

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

2. Можно выполнить операцию чтения, мы не можем удалить элемент.
3. Доступны два метода.

  • общественное логическое значение hasNextElement();
  • общественный объект nextElement();

Итератор

  1. это применимо для всей коллекции

    Iterator itr = c.iterator();  
    where c is any `Collection` class
    
  2. Операция чтения и удаления может быть выполнена

  3. Доступны три метода

    • public boolean hasNext();
    • общественный объект следующий();
    • публичная пустота удалить();

Ограничение в обоих

  • Двигаться только вперед
  • Нет никаких методов для Add object и Replace object
person Vipin Jain    schedule 23.02.2016

1) Основное различие между Iterator и Enumeration заключается в удалении элемента при обходе коллекции. Итератор может удалить элемент во время обхода коллекции, так как у него есть метод remove(). Перечисление не имеет метода remove().

2) Перечисление носит отказоустойчивый характер. Он не генерирует исключение ConcurrentModificationException, если коллекция изменяется во время обхода. Итератор по своей природе отказоустойчив. Он выдает ConcurrentModificationException, если коллекция изменяется во время итерации, отличной от ее собственного метода remove().

3) Enumeration — это устаревший интерфейс, который используется для обхода Vector, Hashtable. Iterator не является устаревшим интерфейсом. Iterator можно использовать для обхода HashMap, LinkedList, ArrayList, HashSet, TreeMap, TreeSet.

person Dhirendra Gautam    schedule 15.04.2020

Если вы пишете свой собственный класс коллекции и расширяете любой из существующих классов или реализуете любой из интерфейсов инфраструктуры коллекций, у вас в основном нет другого выбора, кроме как использовать итератор.

Если по какой-то причине (я не могу придумать) вы создаете собственный класс коллекции, который никаким образом не связан с java.util.Collection или java.util.Map, вы должны все равно реализовать Iterable, чтобы люди могли использовать ваш класс в циклах for.

person Licky Lindsay    schedule 04.06.2009

Основное отличие заключается в том, что Enumeration не предоставляет метод remove(). Более того, Iterator не позволяет одновременно перемещаться и модифицировать базовый объект. У них есть контроль, чтобы увидеть, есть ли одновременные модификации или около того, и, следовательно, требуется больше обработки. Таким образом, производительность Enumeration практически на 50% выше, чем у Iterator. Если нам нужна только навигация без такой синхронизации, просто используйте Enumeration.

person bnguyen82    schedule 10.03.2012
comment
Это правда, что Enumeration не предоставляет метод remove(), но он также не обращает внимания на вызов API remove() Collection. Например, следующий код просто напечатает: AAA, CCC, EEE. -------------------------------------------------- --- Vector‹String› v=new Vector‹String›(6); v. добавить (ААА); v. добавить (ВВВ); v. добавить (CCC); v. добавить (ДДД); v.добавить(ЕЕЕ); v. добавить (FFF); Перечисление‹String› en = v.elements(); while(en.hasMoreElements()) String value=(String) en.nextElement(); System.out.println(значение); v.удалить (значение); - person javauser71; 14.06.2013

Перечисление можно использовать только для устаревшего класса (вектор, стек...), а итератор можно использовать для всех.

person Jay Sheth    schedule 04.09.2016

Итератор, и перечисление используются для извлечения данных, разница в том, что перечисление можно использовать только для устаревших классов, т.е. вектор/стек, тогда как итераторы можно использовать для остальных. Перечисление также можно использовать для набора ключей в картах.

person pavan kumar    schedule 17.08.2012
comment
Где вы увидели, что можно использовать перечисление для наборов ключей карты?? - person Kutzi; 27.07.2014