回答
因爲Enumeration<T>
沒有延伸Iterable<T>
。這是一個example of making Iterable Enumerations。
至於爲什麼這是一個有趣的問題。這不完全是你的問題,但它可以揭示一些問題。從Java Collections API Design FAQ:
爲什麼Iterator不能擴展枚舉?
我們查看 枚舉的方法名稱不幸。它們非常長,並且非常頻繁地使用,它們是 。 鑑於我們正在添加一個方法並創建了一個全新的框架,我們 認爲這將是愚蠢的,不要 趁機改名爲 。當然我們可以在 支持新舊名稱的迭代器,但似乎並不值得。
這基本上告訴我,Sun想要遠離Enumeration,這是非常早期的Java語言,具有相當冗長的語法。
下一個問題:爲什麼枚舉不能迭代? http://stackoverflow.com/questions/27240/why-arent-enumerations-iterable – 2009-08-06 16:37:10
這兩者之間有語義上的區別嗎? (我不熟悉Iterable類)?爲什麼不能在Enumeration上工作呢? – ripper234 2009-08-06 16:37:22
由於枚舉更類似於迭代器,而不是Iterable(請參閱發佈的stackoverflow問題)。作爲解決方法,您可以執行'for(; e.hasMoreElements();){e.getNextElement(); }' – Tim 2009-08-06 16:40:24
新樣式for循環(「foreach」)適用於數組,以及實現Iterable
接口的事物。
它也更類似於Iterator
比Iterable
,所以它是沒有意義的Enumeration
用foreach工作,除非Iterator
沒有太(與事實並非如此)。 Enumeration
也不鼓勵Iterator
。
讓我們在這裏小心一點。棄用意味着在討論API時非常具體。枚舉的使用是不鼓勵的,但它不被棄用。 – ykaganovich 2009-08-06 17:25:45
ykaganovich:好點。我已經更正了答案中的文字。 – 2009-08-06 19:38:40
因爲Enumeration(和大多數從這個接口派生的類)沒有實現Iterable。
您可以嘗試編寫自己的包裝類。
你不應該爲Enumeration編寫一個包裝器,將它變成一個Iterable,而不是你應該爲Iterator創建這樣一個包裝器。迭代器和枚舉對象在迭代方面是有狀態的。可信物不是。 – 2009-08-06 19:40:31
我已經用兩個非常簡單的類來解決這個問題,一個用於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)) {
...
}
使用集合實用程序類,枚舉可以進行迭代,如:
Enumeration headerValues=request.getHeaders("mycustomheader");
List headerValuesList=Collections.list(headerValues);
for(Object headerValueObj:headerValuesList){
... do whatever you want to do with headerValueObj
}
在開始迭代之前將元素複製到新列表中,對於長枚舉應該避免使用此解決方案。將Enumeration轉換爲Iterator的解決方案具有較少的內存開銷。 – 2014-12-18 09:21:19
@EmmanuelBourg但他們有副作用,因爲枚舉是有狀態的。 – 2016-03-17 10:39:51
這是迄今爲止最簡單的答案!不需要依賴關係,並且清晰可讀。謝謝! – 2016-03-30 12:26:44
Enumeration
沒有實現Iterable
,因此不能直接在foreach循環中使用。然而,使用Apache Commons Collections有可能重複的進行枚舉:
for (Object o : new IteratorIterable(new EnumerationIterator(e))) {
...
}
您也可以使用更短的語法與Collections.list()
但這是效率較低(兩次迭代通過元素和使用更多內存):
for (Object o : Collections.list(e))) {
...
}
你的意思是[IteratorIterable](http://commons.apache.org/proper/commons-collections/javadocs/api-release/org/apache/commons/collections4/iterators/IteratorIterable.html)? – luckyluke 2016-11-04 21:13:00
@luckyluke是的,謝謝。我修正了這個例子。 – 2016-11-04 22:51:56
- 1. Java 1.5 Enum:爲什麼我不能在1.5枚枚舉中使用'findBy'?
- 2. 爲什麼Java枚舉不可克隆?
- 3. 爲什麼我不能在目標c中切換枚舉
- 4. 爲什麼我們不能從C#中的枚舉實例訪問枚舉值?
- 5. 爲什麼我不能在Java的內部類中創建枚舉?
- 6. 爲什麼我不能用GcHandle.Alloc引腳枚舉
- 7. 爲什麼我的枚舉不能用作方法參數?
- 8. 爲什麼枚舉包括可枚舉
- 9. 爲什麼這個Java枚舉代碼不能編譯?
- 10. 使用枚舉在Java中
- 11. 爲什麼我不能在foreach中使用這樣的添加?
- 12. 爲什麼JPA枚舉不起作用?
- 13. 爲什麼我不能在我的課堂上使用foreach?
- 14. 爲什麼我們不能有「字符」枚舉類型
- 15. 爲什麼我不能「看到」這個枚舉擴展方法?
- 16. 爲什麼Phobos使用枚舉常量?
- 17. Java枚舉,靜態類變量 - 爲什麼我不能這樣做?
- 18. 爲什麼我們在枚舉中寫入Integer而不是int?
- 19. 枚舉不能使用LINQ
- 20. 不能擴展枚舉;我應該用什麼來代替?
- 21. 爲什麼我不能在forEach函數數組上使用Function.prototype.call?
- 22. 什麼枚舉
- 23. 爲什麼我的枚舉不能在另一個類中找到?
- 24. 使用Java枚舉
- 25. 爲什麼我不能將枚舉導入到我的angular2組件中?
- 26. 爲什麼我不能在Java中
- 27. 爲什麼有些設備不能用SetupDiGetDeviceInterfaceDetail()枚舉?
- 28. Java7/WatchEvent - 爲什麼它不是枚舉?
- 29. 爲什麼使用模型作爲枚舉不好?
- 30. Java在枚舉中的枚舉
枚舉在1998年被Java 1.2中的迭代器所取代,並被保留用於傳統支持。真正的問題是你爲什麼要使用它。可能是因爲你使用強迫你這樣做的圖書館? – 2010-08-27 21:57:10
@彼得 - 是的,外部圖書館是答案。 – ripper234 2010-08-29 20:19:41