EnumSet.of仅支持显式枚举常量,不可用于范围;范围需用EnumSet.range(from,to),闭区间且from不能晚于to;二者均返回可变EnumSet,底层基于位运算高效实现。

EnumSet.of 不能直接构建“范围”(如从 A 到 E)的枚举子集,它只接受明确列出的枚举常量。若想获取连续范围的子集,需配合 EnumSet.range 使用。
EnumSet.of 的真实用途
用于创建包含指定几个枚举值的集合,适合已知具体常量名的场景:
enum Color { RED, GREEN, BLUE, YELLOW, ORANGE }
EnumSet<Color> some = EnumSet.of(Color.RED, Color.BLUE, Color.ORANGE);
- 参数必须是枚举类型的显式常量,不能是变量、表达式或范围
- 至少传一个参数;传空会编译报错
- 返回不可变视图?不,它是可变的——支持 add/remove/clear 等操作
要取“范围”,用 EnumSet.range
当枚举声明顺序有意义(如按业务逻辑排好序),且你想取连续一段时,range(from, to) 是正解:
// 假设 Color 按常用性排序:RED → GREEN → BLUE → YELLOW → ORANGE EnumSet<Color> middle = EnumSet.range(Color.GREEN, Color.YELLOW); // 结果:[GREEN, BLUE, YELLOW]
- from 和 to 必须属于同一枚举类型,且 from 在枚举中不能晚于 to(否则抛 IllegalArgumentException)
- range 包含两端(闭区间),即 from 和 to 都在结果中
- 底层高效:基于位运算,性能优于手动循环添加
组合使用:先 range 再过滤(如需条件筛选)
如果“范围”不是物理顺序,而是满足某条件(例如 name 含 “L” 或 ordinal 在某区间),EnumSet.of 不适用,应:
- 用 EnumSet.allOf 获取全集,再 stream.filter + collect
- 或遍历 values(),判断后用 EnumSet.of(仅限少量匹配项)
- 不推荐手动 new EnumSet —— 构造方法是受保护的,应通过静态工厂方法创建
注意事项
- EnumSet 是专用 Set 实现,内部用 long/int 位向量存储,内存极省、速度极快
- 所有静态工厂方法(of/range/allOf/noneOf)都返回同一类实例(JVM 可能复用)
- 不能存 null,也不允许非该枚举类型的实例,类型安全由编译器和运行时共同保障

















