enumset.of()适用于明确枚举项且数量≤5的场景,语义清晰、初始化快;enumset.range()适用于按声明顺序取连续区间,要求from.ordinal()≤to.ordinal(),闭区间且高效。

Java 中 EnumSet 的 of 和 range 是最常用的两个静态工厂方法,选对场景能省代码、提性能、防出错。
用 EnumSet.of() 快速固定枚举项
适合明确知道要包含哪些枚举常量,且数量不多(通常 ≤5 个)的场景。它直接按参数列表构造集合,语义清晰、初始化快。
- 参数必须是同一枚举类型的显式常量,比如
Color.RED,不能是变量、表达式或字符串 - 支持单个或多个参数重载:
of(e)、of(e1, e2)、of(e1, e2, e3, e4, e5),超过 5 个需配合addAll() - 自动去重、不关心顺序,内部用位向量存储,添加后可修改(如
add()、remove()) - 示例:
EnumSet.of(Season.SPRING, Season.FALL)→ 得到仅含这两个季节的集合
用 EnumSet.range() 按声明顺序取连续段
当枚举值在源码中按业务逻辑顺序定义,且你需要一段“连续区间”时,range 是最优解——简洁、高效、语义准确。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 要求
from和to属于同一枚举类,且from.ordinal() ≤ to.ordinal(),否则运行时报IllegalArgumentException - 闭区间:结果包含
from和to本身,以及中间所有按声明顺序排列的枚举常量 - 底层基于位运算,比循环调用
of或手动add快得多 - 示例:
enum Day { MON, TUE, WED, THU, FRI, SAT, SUN },则EnumSet.range(Day.MON, Day.FRI)返回工作日集合
别混淆:of 不支持范围,range 不支持离散项
两者定位不同,不能互相替代:
-
of只认“列出的每一个”,不识别顺序,也不接受from–to这类区间写法 -
range要求物理声明顺序连续,若枚举中间缺位(比如删了某个常量),range仍会按 ordinal 补全,可能引入意外值 - 混合需求(如“MON–FRI 加上 SUN”)应先
range再add,或用copyOf(range(...)).addAll(of(...))
其他实用搭配建议
实际开发中常组合使用,提升灵活性:
- 需要“除某几个以外的所有” → 先
allOf(MyEnum.class),再removeAll(of(...)) - 需按条件筛选(如 name 含 “L”)→ 用
Stream.of(MyEnum.values()).filter(...).collect(Collectors.toCollection(() → EnumSet.noneOf(MyEnum.class))) - 避免手写
new EnumSet:它是抽象类,无法实例化;所有创建都必须走静态工厂方法
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










