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

为什么我做不到:

Enumeration e = ...
for (Object o : e)
...
69496 次浏览

因为 Enumeration<T>不延伸 Iterable<T>。这是 生成可迭代枚举的示例

至于为什么这是个有趣的问题。这不是你要问的问题,但是它可以解释这个问题。来自 Java 集合 API 设计常见问题解答:

为什么迭代器不扩展枚举?

我们查看 枚举是不幸的 非常长,经常使用。 假设我们添加了一个方法 创造一个全新的框架,我们 觉得不这样做是愚蠢的 利用这个机会 改进名字,我们当然可以 支持新名称和旧名称 迭代器,但似乎 值得。

这基本上告诉我,Sun 希望远离枚举,枚举是非常早期的 Java,语法相当冗长。

New-style-for-loop (“ foreach”)适用于数组和实现 Iterable接口的内容。

它也更类似于 Iterator而不是 Iterable,所以除非 Iterator也使用 foreach,否则 Enumeration使用 foreach 是没有意义的。 Enumeration也不鼓励支持 Iterator

因为枚举(以及从此接口派生的大多数类)不实现 Iterable。

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

我用两个非常简单的类解决了这个问题,一个用于 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)) {
...
}

使用 Collection 实用工具类,枚举可以像下面这样进行迭代:

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


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

Enumeration不实现 Iterable,因此不能直接在 foreach 循环中使用。然而,使用 Apache Commons 集合可以使用以下方法迭代枚举:

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

对于 Collections.list(),您也可以使用更短的语法,但是效率较低(对元素进行两次迭代,使用更多内存) :

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

使用 java 8或更高版本是可能的:

import java.util.Collections;
import java.util.Enumeration;


Enumeration e = ...;
Collections.list(e).forEach(o -> {
... // use item "o"
});

我们可以使用 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 ());
}

我用的是爪哇10