Почему нельзя итерировать перечисления?

В Java 5 и выше у вас есть цикл foreach, который волшебным образом работает со всем, что реализует Iterable:

for (Object o : list) {
  doStuff(o);
}

Однако Enumerable по-прежнему не реализует Iterable, а это означает, что для перебора Enumeration вы должны сделать следующее:

for(; e.hasMoreElements() ;) {
  doStuff(e.nextElement());
}

Кто-нибудь знает, есть ли причина, по которой Enumeration до сих пор не реализует Iterable?

Редактировать: В качестве пояснения я не говорю о языковой концепции перечислить, я говорю о специфическом для Java классе в Java API под названием «Перечисление».

Разве это не должно быть doStuff (e.nextElement ()) внутри блока?

Hans L 13.01.2010 18:00
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
66
1
20 340
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Перечисление не было изменено для поддержки Iterable, потому что это интерфейс, а не конкретный класс (например, Vector, который был изменен для поддержки интерфейса коллекций).

Если бы Enumeration была изменена для поддержки Iterable, это сломало бы кучу кода людей.

Тем не менее, учитывая, что существует поддержка для каждого обе Iterable и массивов, почему sun также не включил Enumerable?

akuhn 26.11.2008 19:13

@Adrian Kuhn: они не включали поддержку для каждого для Iterator, а Enumerable ведет себя как Iterator, а не Iterable.

Laurence Gonsalves 06.08.2009 20:43

Перечисление НЕ ИТЕРАКТИВНО. Enumeratrion на самом деле является IteraTOR (но без «удаления») stackoverflow.com/a/8197868/117220. С этим уточнением ответ заключается в том, что это нарушит существующие API. Было бы возможно сделать это с обратной совместимостью, если бы частичная реализация разрешена в интерфейсах (например, в чертах Scala).

Petr Gladkikh 01.06.2012 07:49

@PetrGladkikh: Но в Java 8 все еще не исправили.

JohnEye 09.06.2015 16:51

@JohnEye Даже с использованием методов по умолчанию в Java 8 невозможно полностью реализовать Enumeration на основе Iterable. Нечего «исправить»; Enumeration и Iterable не являются логически эквивалентными типами, и утилита преобразования для правильного устранения разрыва между ними уже предусмотрена в Collections.list().

erickson 09.06.2017 16:40

AFAIK Перечисление вроде как "устарел":

Iterator takes the place of Enumeration in the Java collections framework

Я надеюсь, что они изменят API сервлетов с JSR 315, чтобы использовать Iterator вместо Enumeration.

Enumeration не имеет смысла внедрять Iterable. Iterable - заводской метод для Iterator. Enumeration аналогичен Iterator и поддерживает состояние только для одного перечисления.

Так что будьте осторожны, пытаясь обернуть Enumeration как Iterable. Если кто-то передаст мне Iterable, я буду считать, что могу вызывать iterator() несколько раз, создавая столько экземпляров Iterator, сколько хочу, и повторяя каждый из них независимо. Упакованный Enumeration не будет выполнять этот контракт; не позволяйте упакованному Enumeration ускользать от вашего собственного кода. (Кстати, я заметил, что DirectoryStream в Java 7 именно таким образом нарушает ожидания, и ему также нельзя позволить «ускользнуть».)

Enumeration похож на Iterator, а не на Iterable. Collection - это Iterable. Iterator - нет.

Вы не можете этого сделать:

Vector<X> list = …
Iterator<X> i = list.iterator();
for (X x : i) {
    x.doStuff();
}

Так что это было бы бессмысленно:

Vector<X> list = …
Enumeration<X> i = list.enumeration();
for (X x : i) {
    x.doStuff();
}

Не существует эквивалента Enumerable для Iterable. Его можно было бы добавить, ничего не нарушая, чтобы работать с циклами for, но какой в ​​этом смысл? Если вы можете реализовать этот новый интерфейс Enumerable, почему бы просто не реализовать вместо него Iterable?

В качестве простого и чистый способа использования Enumeration с расширенным циклом for преобразование в ArrayList с помощью java.util.Collections.list.

for (TableColumn col : Collections.list(columnModel.getColumns()) {

(javax.swing.table.TableColumnModel.getColumns возвращает Enumeration.)

Обратите внимание, это может быть немного менее эффективным.

Забавно: это (столбцы в модели столбцов) - точная причина, по которой я нашел этот вопрос.

Dave 20.04.2011 22:03

Если вы хотите, чтобы он был немного чище синтаксически, вы можете использовать:

while(e.hasMoreElements()) {
  doStuff(e.nextElement());
}

Другие вопросы по теме