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

时间:2009-08-06 16:34:42

标签: java loops

为什么我不能这样做:

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

8 个答案:

答案 0 :(得分:59)

因为Enumeration<T>没有延伸Iterable<T>。这是一个example of making Iterable Enumerations

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

  

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

     

我们查看方法名称   枚举是不幸的。他们是   很长,而且经常使用。   鉴于我们正在添加一种方法和   我们创造了一个全新的框架   觉得不这样做是愚蠢的   利用这个机会   改善名字。我们当然可以   支持新旧名称   迭代器,但似乎没有   值得的。

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

答案 1 :(得分:37)

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

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

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

答案 2 :(得分: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"); }
}

可以使用静态实用工具方法(这是我的偏好):

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

答案 3 :(得分:3)

new-style-for-loop(“foreach”)适用于数组,以及实现Iterable接口的东西。

它也更类似于Iterator而不是Iterable,因此Enumeration使用foreach是没有意义的,除非Iterator也这样做(并且它没有“T)。 我们也不鼓励Enumeration支持Iterator

答案 4 :(得分:1)

Enumeration未实现Iterable,因此无法在foreach循环中直接使用。但是,使用Apache Commons Collections可以使用以下内容迭代枚举:

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

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

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

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

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

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

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

答案 7 :(得分:0)

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

一个例子:

dt = datetime.strptime(realTimeStamp,"%d/%b/%Y:%H:%M:%S%z")
print(dt.date()) # results to 2020-07-27

我在Java 10中做到了