Подтвердить что ты не робот

Почему я не могу использовать foreach в Java Enumeration?

Почему я не могу:

Enumeration e = ...
for (Object o : e)
  ...
4b9b3361

Ответ 1

Поскольку Enumeration<T> не распространяется Iterable<T>. Ниже приведен пример Часто задаваемые вопросы API API коллекций Java:

Почему Iterator не расширяет Enumeration?

Мы рассматриваем имена методов для Перечисление как неудачное. Они очень долго и очень часто используется. Учитывая, что мы добавляем метод и создавая совершенно новую структуру, мы чувствовал, что было бы глупо не воспользоваться возможностью улучшить имена. Конечно, мы могли бы поддерживать новые и старые имена в Итератор, но это не кажется стоит.

Это в основном подсказывает мне, что Sun хочет дистанцироваться от Enumeration, которая очень ранняя Java с довольно подробным синтаксисом.

Ответ 2

Используя класс утилиты Collections, Enumeration можно сделать следующим образом:

Enumeration headerValues=request.getHeaders("mycustomheader");
List headerValuesList=Collections.list(headerValues);

for(Object headerValueObj:headerValuesList){
 ... do whatever you want to do with headerValueObj
}

Ответ 3

Я решил эту проблему с двумя очень простыми классами: один для 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)) {
    ...
    }

Ответ 4

Новый стиль для цикла ( "foreach" ) работает с массивами и с теми, которые реализуют интерфейс Iterable.

Он также более похож на Iterator, чем на Iterable, поэтому для Enumeration не имеет смысла работать с foreach, если только Iterator тоже (а это не так). Enumeration также обескураживается в пользу Iterator.

Ответ 5

Enumeration не реализует Iterable и поэтому не может использоваться непосредственно в цикле foreach. Однако, используя Apache Commons Collections, можно перебирать нумерацию с помощью:

for (Object o : new IteratorIterable(new EnumerationIterator(e))) {
    ...
}

Вы также можете использовать более короткий синтаксис с Collections.list(), но это менее эффективно (две итерации по элементам и больше использования памяти):

for (Object o : Collections.list(e))) {
    ...
}

Ответ 6

Поскольку перечисление (и большинство классов, полученных из этого интерфейса) не реализует Iterable.

Вы можете попробовать написать свой собственный класс-оболочку.