簡體   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