EnumSet 是 Java 專為枚舉類型設計的高效 Set 實現,內部使用位向量 (long/long[]) 存儲,所有操作均為位運算,性能極佳且類型安全。本文通過完整示例演示 EnumSet 的創建、元素增刪、集合運算 (補集、範圍) 等核心功能。
定義一周七天枚舉,作為 EnumSet 的元素類型。
public enum Weeks {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
靜態導入枚舉常量簡化代碼。演示 noneOf 創建空集、add/remove 單元素操作、complementOf 獲取補集、range 獲取範圍集合、addAll/removeAll 批量操作。
import static cn.edu.xidian.crytoll.Weeks.MONDAY;
import static cn.edu.xidian.crytoll.Weeks.THURSDAY;
import java.util.EnumSet;
public class EnumSetTest {
public static void main(String[] args) {
// 1. 創建空 EnumSet
EnumSet<Weeks> week = EnumSet.noneOf(Weeks.class);
System.out.println("初始空集合:" + week); // []
// 2. 添加單個元素
week.add(MONDAY);
System.out.println("添加 MONDAY:" + week); // [MONDAY]
// 3. 移除單個元素
week.remove(MONDAY);
System.out.println("移除 MONDAY:" + week); // []
// 4. 獲取補集 (所有未在集合中的元素) 並添加
week.addAll(EnumSet.complementOf(week));
System.out.println("添加補集 (全集):" + week); // [MONDAY, TUESDAY, ..., SUNDAY]
// 5. 移除範圍 [MONDAY, THURSDAY] (含端點)
week.removeAll(EnumSet.range(MONDAY, THURSDAY));
System.out.println("移除範圍 MONDAY-THURSDAY:" + week); // [FRIDAY, SATURDAY, SUNDAY]
}
}
初始空集合:[]
添加 MONDAY:[MONDAY]
移除 MONDAY:[]
添加補集 (全集):[MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY]
移除範圍 MONDAY-THURSDAY:[FRIDAY, SATURDAY, SUNDAY]
| 方法 | 說明 | 典型用途 |
|---|---|---|
| noneOf(Class<E>) | 創建空集合 | 初始化後動態添加 |
| allOf(Class<E>) | 創建包含所有枚舉值的集合 | 快速獲取全集 |
| of(E first, E... rest) | 創建包含指定元素的集合 | 已知元素快速構建 |
| range(E from, E to) | 創建範圍集合 [from, to] (含端點) | 連續枚舉值區間選擇 |
| complementOf(EnumSet<E>) | 創建補集 (全集 - 指定集合) | 反向選擇、排除特定值 |
| copyOf(Collection<E>) | 從集合複製創建 | 轉換普通集合為 EnumSet |
| 特性 | EnumSet | HashSet<Enum> | BitSet |
|---|---|---|---|
| 存儲結構 | 位向量 (long/long[]) | 哈希表 (Node[]) | 位向量 (long[]) |
| 類型安全 | ✅ 編譯期約束 | ✅ 泛型約束 | ❌ 無類型概念 |
| 記憶體 (64值) | 8 字節 | ~數 KB | 8 字節 |
| contains 性能 | O(1) 位運算 | O(1) 哈希查找 | O(1) 位運算 |
| 語義化 API | ✅ range/complementOf | ❌ 通用 Set API | ❌ 索引操作 |
| 迭代順序 | 枚舉聲明順序 | 無序 | 索引順序 |