为什么我不能在Java Enumeration上使用foreach?

rip*_*234 66 java loops

为什么我不能这样做:

Enumeration e = ...
for (Object o : e)
  ...
Run Code Online (Sandbox Code Playgroud)

cle*_*tus 60

因为Enumeration<T>没有延伸Iterable<T>.以下是制作Iterable Enumerations示例.

至于为什么这是一个有趣的问题.这不是你的问题,但它揭示了它.来自Java Collections API Design FAQ:

为什么Iterator不扩展枚举?

我们将Enumeration的方法名称视为不幸.它们很长,而且经常使用.鉴于我们正在添加一种方法并创建一个全新的框架,我们认为不利用这个机会改进名称是愚蠢的.当然,我们可以在Iterator中支持新旧名称,但这似乎不值得.

这基本上告诉我,Sun希望将自己与Enumeration保持距离,Enumeration是非常早期的Java,语法相当冗长.

  • 下一个问题:为什么枚举不可以进行?http://stackoverflow.com/questions/27240/why-arent-enumerations-iterable (19认同)
  • 因为Enumerations更类似于Iterator,而不是Iterable(参见stackoverflow问题mmyers发布).作为一种解决方法,你可以做`for(; e.hasMoreElements();){e.getNextElement(); }` (4认同)
  • 但是`Iterators`也不是'Iterable`.你不能做`for(obj:itr)`.这样做的原因是`Iterable`实际上是*可重复迭代*,而迭代器只能迭代一次. (4认同)
  • 这并不能解释为什么Sun/Oracle不允许在新的`for`语法中使用`Enumeration`以及`Iterable`和`array`. (4认同)

小智 43

使用Collections实用程序类,Enumeration可以迭代,如:

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

for(Object headerValueObj:headerValuesList){
 ... do whatever you want to do with headerValueObj
}
Run Code Online (Sandbox Code Playgroud)

  • 在开始迭代之前,元素被复制到新的列表中,对于长枚举,应避免使用此解决方案.将Enumeration转换为Iterator的解决方案具有较少的内存开销. (2认同)

Law*_*Dol 6

我用两个非常简单的类解决了这个问题,一个用于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"); }
}
Run Code Online (Sandbox Code Playgroud)

哪个可以使用静态实用程序方法(这是我的偏好):

/**
 * 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)) {
    ...
    }
Run Code Online (Sandbox Code Playgroud)

或者通过实例化类:

for(String val: new IterableEnumeration<String>(enm)) {
    ...
    }
Run Code Online (Sandbox Code Playgroud)


Lau*_*ves 5

新式 for 循环(“foreach”)适用于数组以及实现Iterable

它也比Iteratorto更相似,因此与 foreach 一起使用Iterable是没有意义的,除非也这样做了(而且它没有这样做)。 也是不赞成的。EnumerationIteratorEnumerationIterator

  • 让我们小心这里的术语。在讨论 API 时,弃用意味着非常具体的事情。不鼓励使用枚举,但不建议使用它。 (4认同)