在 Java 集合框架中,Enumeration 與 Iterator 是兩種核心遍歷介面。雖然功能相似,但設計理念、功能豐富度與現代適用性有顯著差異。本文深入剖析兩者差異、效能表現與最佳實踐。
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map.Entry;
public class TraverseHashtable {
public static void main(String[] args) {
// 初始化 10,000 筆測試資料
Hashtable<String, String> ht = new Hashtable<>();
for (int i = 0; i < 10000; i++) {
ht.put("Key=" + i, "Val=" + i);
}
// 1. Enumeration 遍歷 keys
long start = System.currentTimeMillis();
Enumeration<String> enKeys = ht.keys();
while (enKeys.hasMoreElements()) {
enKeys.nextElement();
}
System.out.println("Enumeration keys 耗時:" + (System.currentTimeMillis() - start) + " ms");
// 2. Enumeration 遍歷 elements (值)
start = System.currentTimeMillis();
Enumeration<String> enElements = ht.elements();
while (enElements.hasMoreElements()) {
enElements.nextElement();
}
System.out.println("Enumeration elements 耗時:" + (System.currentTimeMillis() - start) + " ms");
// 3. Iterator 遍歷 keySet
start = System.currentTimeMillis();
Iterator<String> itKeys = ht.keySet().iterator();
while (itKeys.hasNext()) {
itKeys.next();
}
System.out.println("Iterator keySet 耗時:" + (System.currentTimeMillis() - start) + " ms");
// 4. Iterator 遍歷 entrySet (鍵值對)
start = System.currentTimeMillis();
Iterator<Entry<String, String>> itEntries = ht.entrySet().iterator();
while (itEntries.hasNext()) {
itEntries.next();
}
System.out.println("Iterator entrySet 耗時:" + (System.currentTimeMillis() - start) + " ms");
}
}
| 維度 | Enumeration | Iterator |
|---|---|---|
| 推出版本 | JDK 1.0 (古老) | JDK 1.2 (集合框架標準) |
| 核心方法 | hasMoreElements(), nextElement() | hasNext(), next(), remove() |
| 移除支援 | ❌ 無法移除元素 | ✅ 支援安全移除 |
| 泛型支援 | JDK 1.5 後添加 | 原生支援泛型 |
| 適用集合 | Vector、Hashtable 等舊類 | 所有 Collection 實作類 |
| 故障快速機制 | ❌ 無 | ✅ fail-fast 機制 |
早期傳言「Enumeration 效能優於 Iterator」,實測發現:
結論: 不要為了微乎其微的效能差異選擇 Enumeration,功能缺失風險更大。
remove(),無法在遍歷中安全刪除ConcurrentModificationException,隱患難發現維護極舊版系統 (JDK 1.1 時代) 或被迫呼叫舊版 API 回傳 Enumeration 時,為相容性不得不使用。新專案零理由使用。
entrySet().iterator(),單次遍歷同時獲取鍵值,效能最佳forEach、Stream API 等函數式寫法,更簡潔ConcurrentHashMap 等並發集合,其 Iterator 為弱一致性,無拋異常風險掌握遍歷介面的演進歷史與核心差異,能讓你在代碼審查、效能調優、舊系統重構時做出專業判斷。