为什么我不能在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。
你可以尝试编写你自己的包装类。