Почему перечисления не являются итеративными?
-
09-06-2019 - |
Вопрос
В Java 5 и выше у вас есть цикл foreach, который волшебным образом работает со всем, что реализует Iterable
:
for (Object o : list) {
doStuff(o);
}
Однако, Enumerable
все еще не реализует Iterable
, что означает повторение по Enumeration
вы должны выполнить следующее:
for(; e.hasMoreElements() ;) {
doStuff(e.nextElement());
}
Кто-нибудь знает, есть ли причина, почему Enumeration
все еще не реализует Iterable
?
Редактировать: В качестве пояснения, я не говорю о языковой концепции перечисление, я говорю о специфичном для Java классе в Java API, который называется 'Перечисление'.
Решение
Перечисление не было изменено для поддержки Iterable, потому что это интерфейс, а не конкретный класс (например, Vector, который был изменен для поддержки интерфейса Collections).
Если бы перечисление было изменено для поддержки Iterable, это нарушило бы работу множества людей с кодом.
Другие советы
Как простое и чистый способ использования перечисления с расширенным циклом for, преобразуйте в ArrayList с помощью java.util.Collections.list.
for (TableColumn col : Collections.list(columnModel.getColumns()) {
(javax.swing.table.TableColumnModel.getColumns возвращает перечисление.)
Обратите внимание, что это может быть немного менее эффективно.
Это не имеет смысла для Enumeration
для реализации Iterable
. Iterable
является заводским методом для Iterator
. Enumeration
аналогичен Iterator
, и поддерживает состояние только для одного перечисления.
Итак, будьте осторожны, пытаясь обернуть Enumeration
в качестве Iterable
.Если кто-то передаст мне Iterable
, Я буду считать , что я могу позвонить iterator()
на нем неоднократно, создавая как можно больше Iterator
экземпляры, какие я хочу, и повторение независимо для каждого из них.Завернутый Enumeration
не будет выполнять этот контракт;не позволяйте своему обернутому Enumeration
избавьтесь от своего собственного кода.(Кстати, я заметил, что Java 7 DirectoryStream
нарушает ожидания именно таким образом, и ему также не следует позволять "сбежать".)
Enumeration
это похоже на Iterator
, а не Iterable
.A 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
вместо этого?
Перечисление AFAIK является своего рода "устаревший":
Итератор заменяет Перечисление в Java collections framework
Я надеюсь, что они изменят Servlet API с помощью JSR 315, чтобы использовать Iterator вместо перечисления.
Если вы просто хотите, чтобы он был синтаксически немного чище, вы можете использовать:
while(e.hasMoreElements()) {
doStuff(e.nextElement());
}