enummap用枚举ordinal作数组下标实现o(1)访问,需显式传入枚举类字面量初始化,底层为固定长度object[],键不可为null,遍历顺序即枚举声明顺序,适合状态映射等密集使用场景。

直接用 EnumMap 替代 HashMap 存枚举键,就能获得接近数组的访问速度——它不走哈希,而是用枚举的 ordinal() 当下标,一次内存读写就完成 get/put。
必须传入枚举类字面量初始化
EnumMap 无法靠泛型推断类型,构造时必须显式传入 MyEnum.class:
- ✅ 正确:
new EnumMap<status string>(Status.class)</status> - ❌ 错误:
new EnumMap()(编译失败)或传错类型(如HashMap.class) - Java 9+ 可用静态工厂简化小规模初始化:
EnumMap.of(Status.PENDING, "处理中", Status.DONE, "已完成")
底层是数组,不是哈希表
它内部维护一个 Object[],长度等于枚举常量总数(Status.values().length),每个位置对应一个 ordinal 值:
-
put(Status.PENDING, "abc")→ 写入table[0] -
get(Status.DONE)→ 直接读取table[2](假设DONE.ordinal() == 2) - 跳过哈希计算、桶查找、链表遍历、扩容判断和装箱开销
注意 null 和顺序语义
Key 绝对不能为 null(会立即抛 NullPointerException),value 可为 null,但需谨慎区分语义:
- 用
containsKey(key)判断键是否存在,不要依赖get(key) == null - 遍历顺序固定为枚举声明顺序(即
values()顺序),天然有序,无需额外排序 - 所有枚举常量都预留空间——哪怕只存 3 个值,100 个常量的枚举也会分配 100 元素数组
适合场景与避坑提醒
它不是万能替代品,关键看是否匹配约束:
- ✅ 推荐:状态机映射(
State → Set<nextstate></nextstate>)、HTTP 状态码描述、权限开关配置、订单类型统计等 - ❌ 慎用:枚举常量超几百且稀疏使用;枚举可能动态扩展(如插件机制);需要多线程并发写入(需手动同步或包装成线程安全)
- ⚠️ 不支持泛型枚举(如
Enum>),所有 key 必须来自同一具体枚举类
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











