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

ih99xse1  于 2023-05-12  发布在  Java
关注(0)|答案(8)|浏览(110)

为什么我不能做:

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

jhdbpxl91#

因为Enumeration<T>没有扩展Iterable<T>。这里是example of making Iterable Enumerations
为什么这是一个有趣的问题。这不是你的问题,但它揭示了一些问题。关于Java Collections API Design FAQ

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

我们认为Enumeration的方法名是不恰当的。它们很长,而且经常使用。考虑到我们正在添加一个方法并创建一个全新的框架,我们觉得不利用这个机会来改进名称是愚蠢的。当然,我们可以在Iterator中支持新的和旧的名称,但这似乎不值得。
这基本上表明Sun希望与Enumeration保持距离,Enumeration是非常早期的Java,语法相当冗长。

nwsw7zdq

nwsw7zdq2#

使用Collections实用程序类,Enumeration可以像这样迭代:

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

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

kyvafyod3#

我已经用一个简单的 Package 器解决了这个问题,如下所示:

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

1wnzp6jl4#

新样式的for-loop(“foreach”)适用于数组和实现Iterable接口的对象。
它也更类似于Iterator而不是Iterable,所以Enumeration与foreach一起工作是没有意义的,除非Iterator也这样做(它没有)。Enumeration也不被鼓励,而支持Iterator

uemypmqf

uemypmqf5#

在Java 8和更高版本中,这是可能的:

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

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

xzlaal3s6#

Enumeration没有实现Iterable,因此不能直接用于foreach循环。但是,使用Apache Commons Collections可以使用以下命令迭代枚举:

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

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

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

col17t5w7#

因为Enumeration(以及大多数从该接口派生的类)不实现Iterable。
您可以尝试编写自己的 Package 器类。

s2j5cfk0

s2j5cfk08#

Enumeration遗留类类似于现代的Iterator类。两者都表示对数据的当前迭代。
增强的for循环设计用于Iterable和数组,但值得注意的是 * 不 * 用于IteratorIterable提供了一个iterator方法,该方法在其数据上返回Iterator
虽然不可能在Enumeration或其现代的Iterator等效物中使用增强的for循环,但Iterator中的forEachRemaining方法(在Java 8中添加)提供了类似的功能。与Enumeration.asIterator(在Java 9中添加)结合使用,允许以与增强的for循环类似的方式迭代枚举:

Enumeration<Object> e = ...
e.asIterator().forEachRemaining(o -> {
  // ...
});

相关问题