繁体   English   中英

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

[英]Why can't I use foreach on Java Enumeration?

为什么我不能这样做:

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

因为Enumeration<T>不扩展Iterable<T> 这是制作可迭代枚举示例

至于为什么这是一个有趣的问题。 这不完全是您的问题,但它对此有所了解。 来自Java 集合 API 设计常见问题解答

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

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

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

使用 Collections 实用程序类,可以使枚举可迭代,例如:

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

新式 for 循环(“foreach”)适用于数组和实现Iterable接口的事物。

它也更类似于Iterator不是Iterable ,因此Enumeration与 foreach 一起工作是没有意义的,除非Iterator也这样做(并且它没有)。 Enumeration也不鼓励使用Iterator

使用 java 8 及更高版本,这是可能的:

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

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

Enumeration不实现Iterable ,因此不能直接在 foreach 循环中使用。 但是,使用Apache Commons Collections可以通过以下方式迭代枚举:

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

您也可以在Collections.list()使用更短的语法,但这效率较低(元素上的两次迭代和更多的内存使用):

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

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

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

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

我在java 10中做到了

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM