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

为什么我不能这样做:

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

因为Enumeration<T>不能扩展Iterable<T> 。 这是一个使Iterable枚举的例子 。

至于为什么这是一个有趣的问题。 这不完全是你的问题,但它揭示了一些光。 从Java Collections APIdeviseFAQ :

为什么Iterator不能扩展枚举?

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

这基本上向我暗示,Sun希望与Enumeration保持距离,Enumeration是非常早期的Java语言,具有相当冗长的语法。

使用集合实用程序类,枚举可以进行迭代,如:

 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))) { ... } 

因为Enumeration(和大多数从这个接口派生的类)不能实现Iterable。

你可以尝试编写你自己的包装类。