Почему я не могу:
Enumeration e = ...
for (Object o : e)
...
Почему я не могу:
Enumeration e = ...
for (Object o : e)
...
Поскольку Enumeration<T>
не распространяется Iterable<T>
. Ниже приведен пример Часто задаваемые вопросы API API коллекций Java:
Почему Iterator не расширяет Enumeration?
Мы рассматриваем имена методов для Перечисление как неудачное. Они очень долго и очень часто используется. Учитывая, что мы добавляем метод и создавая совершенно новую структуру, мы чувствовал, что было бы глупо не воспользоваться возможностью улучшить имена. Конечно, мы могли бы поддерживать новые и старые имена в Итератор, но это не кажется стоит.
Это в основном подсказывает мне, что Sun хочет дистанцироваться от Enumeration, которая очень ранняя Java с довольно подробным синтаксисом.
Используя класс утилиты Collections, Enumeration можно сделать следующим образом:
Enumeration headerValues=request.getHeaders("mycustomheader");
List headerValuesList=Collections.list(headerValues);
for(Object headerValueObj:headerValuesList){
... do whatever you want to do with headerValueObj
}
Я решил эту проблему с двумя очень простыми классами: один для Enumeration
и один для Iterator
. Оболочка перечисления выглядит следующим образом:
static class IterableEnumeration<T>
extends Object
implements Iterable<T>, Iterator<T>
{
private final Enumeration<T> enumeration;
private boolean used=false;
IterableEnumeration(final Enumeration<T> enm) {
enumeration=enm;
}
public Iterator<T> iterator() {
if(used) { throw new IllegalStateException("Cannot use iterator from asIterable wrapper more than once"); }
used=true;
return this;
}
public boolean hasNext() { return enumeration.hasMoreElements(); }
public T next() { return enumeration.nextElement(); }
public void remove() { throw new UnsupportedOperationException("Cannot remove elements from AsIterator wrapper around Enumeration"); }
}
который может использоваться либо со статическим методом утилиты (что является моим предпочтением):
/**
* Convert an `Enumeration<T>` to an `Iterable<T>` for a once-off use in an enhanced for loop.
*/
static public <T> Iterable<T> asIterable(final Enumeration<T> enm) {
return new IterableEnumeration<T>(enm);
}
...
for(String val: Util.asIterable(enm)) {
...
}
или путем создания экземпляра класса:
for(String val: new IterableEnumeration<String>(enm)) {
...
}
Новый стиль для цикла ( "foreach" ) работает с массивами и с теми, которые реализуют интерфейс Iterable
.
Он также более похож на Iterator
, чем на Iterable
, поэтому для Enumeration
не имеет смысла работать с foreach, если только Iterator
тоже (а это не так).
Enumeration
также обескураживается в пользу Iterator
.
Enumeration
не реализует Iterable
и поэтому не может использоваться непосредственно в цикле foreach. Однако, используя Apache Commons Collections, можно перебирать нумерацию с помощью:
for (Object o : new IteratorIterable(new EnumerationIterator(e))) {
...
}
Вы также можете использовать более короткий синтаксис с Collections.list()
, но это менее эффективно (две итерации по элементам и больше использования памяти):
for (Object o : Collections.list(e))) {
...
}
Поскольку перечисление (и большинство классов, полученных из этого интерфейса) не реализует Iterable.
Вы можете попробовать написать свой собственный класс-оболочку.