为什么我不能在 Java 枚举上使用 foreach?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1240077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't I use foreach on Java Enumeration?
提问by ripper234
Why can't I do:
为什么我不能这样做:
Enumeration e = ...
for (Object o : e)
...
采纳答案by cletus
Because Enumeration<T>
doesn't extend Iterable<T>
. Here is an example of making Iterable Enumerations.
因为Enumeration<T>
不扩展Iterable<T>
。这是制作可迭代枚举的示例。
As to why that's an interesting question. This isn't exactly your question but it sheds some light on it. From the Java Collections API Design FAQ:
至于为什么这是一个有趣的问题。这不完全是您的问题,但它对此有所了解。来自Java 集合 API 设计常见问题解答:
Why doesn't Iterator extend Enumeration?
We view the method names for Enumeration as unfortunate. They're very long, and very frequently used. Given that we were adding a method and creating a whole new framework, we felt that it would be foolish not to take advantage of the opportunity to improve the names. Of course we could support the new and old names in Iterator, but it doesn't seem worthwhile.
为什么迭代器不扩展枚举?
我们认为 Enumeration 的方法名称很不幸。它们很长,而且使用频率很高。鉴于我们正在添加一个方法并创建一个全新的框架,我们认为不利用这个机会改进名称是愚蠢的。当然我们可以在Iterator中支持新旧名称,但似乎不值得。
That basically suggests to me that Sun wants to distance themselves from Enumeration, which is very early Java with quite a verbose syntax.
这基本上向我表明,Sun 希望与 Enumeration 保持距离,Enumeration 是非常早期的 Java,具有相当冗长的语法。
回答by Laurence Gonsalves
The new-style-for-loop ("foreach") works on arrays, and things that implement the Iterable
interface.
新式 for 循环(“foreach”)适用于数组和实现Iterable
接口的事物。
It's also more analogous to Iterator
than to Iterable
, so it wouldn't make sense for Enumeration
to work with foreach unless Iterator
did too (and it doesn't).
Enumeration
is also discouraged in favor of Iterator
.
它也Iterator
比 to更类似Iterable
,因此Enumeration
除非Iterator
也这样做(并且没有这样做),否则与 foreach 一起工作是没有意义的。
Enumeration
也劝阻赞成Iterator
。
回答by Stroboskop
Because an Enumeration (and most classes derived from this interface) does not implement Iterable.
因为枚举(以及从该接口派生的大多数类)没有实现 Iterable。
You can try to write your own wrapper class.
您可以尝试编写自己的包装类。
回答by Lawrence Dol
I have solved this problem with two very simple classes, one for Enumeration
and one for Iterator
. The enumeration wrapper is as follows:
我已经用两个非常简单的类解决了这个问题,一个是 for Enumeration
,一个是 for 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"); }
}
Which can be used either with a static utility method (which is my preference):
可以与静态实用程序方法一起使用(这是我的偏好):
/**
* 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)) {
...
}
or by instantiating the class:
或通过实例化类:
for(String val: new IterableEnumeration<String>(enm)) {
...
}
回答by user1555669
Using Collections utility class, Enumeration can be made iterable like:
使用 Collections 实用程序类,可以使枚举可迭代,例如:
Enumeration headerValues=request.getHeaders("mycustomheader");
List headerValuesList=Collections.list(headerValues);
for(Object headerValueObj:headerValuesList){
... do whatever you want to do with headerValueObj
}
回答by Emmanuel Bourg
Enumeration
doesn't implement Iterable
and as such can't be used directly in a foreach loop. However using Apache Commons Collectionsit's possible to iterate over an enumeration with:
Enumeration
没有实现Iterable
,因此不能直接在 foreach 循环中使用。但是,使用Apache Commons Collections可以通过以下方式迭代枚举:
for (Object o : new IteratorIterable(new EnumerationIterator(e))) {
...
}
You could also use a shorter syntax with Collections.list()
but this is less efficient (two iterations over the elements and more memory usage) :
您也可以使用较短的语法,Collections.list()
但效率较低(元素上的两次迭代和更多的内存使用):
for (Object o : Collections.list(e))) {
...
}
回答by slartidan
With java 8 and beyond this is possible:
使用 java 8 及更高版本,这是可能的:
import java.util.Collections;
import java.util.Enumeration;
Enumeration e = ...;
Collections.list(e).forEach(o -> {
... // use item "o"
});