Почему я не могу:
Enumeration e = ...
for (Object o : e)
...
Почему я не могу:
Enumeration e = ...
for (Object o : e)
...
Поскольку Enumeration<T>
не расширяет _ 2_. Вот пример создания итерируемых перечислений.
Что касается того, почему это интересный вопрос. Это не совсем ваш вопрос, но он проливает на него свет. Из часто задаваемых вопросов по дизайну API коллекций Java:
Почему Iterator не расширяет Enumeration?
Мы считаем имена методов для Enumeration неудачными. Они очень длинные и используются очень часто. Учитывая, что мы добавляли метод и создавали совершенно новую структуру, мы чувствовали, что было бы глупо не воспользоваться возможностью улучшить имена. Конечно, мы могли бы поддерживать новые и старые имена в Iterator, но это не имеет смысла.
Это в основном подсказывает мне, что Sun хочет дистанцироваться от Enumeration, который является очень ранней версией Java с довольно подробным синтаксисом.
for(; e.hasMoreElements(); ) { e.getNextElement(); }
- person Tim; 06.08.2009
Iterators
тоже не Iterable
. Вы не можете сделать for (obj : itr)
. Причина этого в том, что Iterable
действительно повторяется многократно, тогда как итератор может повторяться только один раз.
- person oxbow_lakes; 06.08.2009
Enumeration
в новом синтаксисе for
, а также Iterable
и array
.
- person mjaggard; 02.04.2013
Используя служебный класс 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
.
С java 8 и выше это возможно:
import java.util.Collections;
import java.util.Enumeration;
Enumeration e = ...;
Collections.list(e).forEach(o -> {
... // use item "o"
});
Enumeration
не реализует Iterable
и поэтому не может использоваться непосредственно в цикле foreach. Однако, используя коллекции Apache Commons, можно перебирать перечисление с помощью:
for (Object o : new IteratorIterable(new EnumerationIterator(e))) {
...
}
Вы также можете использовать более короткий синтаксис с Collections.list()
, но это менее эффективно (две итерации по элементам и большее использование памяти):
for (Object o : Collections.list(e))) {
...
}
Поскольку Enumeration (и большинство классов, производных от этого интерфейса) не реализует Iterable.
Вы можете попробовать написать свой собственный класс-оболочку.
Мы можем использовать цикл for для перебора перечисления, используя .values()
method
which returns all the elements contained in the enumeration.
Пример :
for (USERS_ROLES userRole: USERS_ROLES .values ()) {
System.out.println ("This is one user role:" + userRole.toString ());
}
Я сделал это в java 10