enummap 比 hashmap 更快更省内存,因其用枚举 ordinal 作数组下标实现 o(1) 查找;必须用具体枚举类构造,键仅限该枚举实例,不允许 null 键或非法类型,遍历按声明顺序,视图不可结构性修改。

直接用枚举常量当 Key,EnumMap 比 HashMap 快得多——它不靠哈希,而是用数组下标直取,O(1) 查找,没装箱、没冲突、内存还省约 40%。
必须用具体枚举类构造
创建时得明确传入枚举类型字节码,比如 new EnumMapHttpStatus.values().length 预分配固定长度数组,所有操作都按 key.ordinal() 算下标访问。
- 写成
new EnumMap<enum>, V>(...)</enum>或通配符泛型 → 编译失败 - 用反射获取 class 再传入(如
clazz = HttpStatus.class; new EnumMap(clazz))→ 运行时可能抛IllegalArgumentException - 键类型写成
String或自定义常量类假装是枚举 → 底层索引失效,性能优势归零
Key 只能是该枚举的有效实例
EnumMap 对键类型极其严格:只认你构造时指定的那个枚举类的合法常量。
-
map.put(null, "x")→ 立刻抛NullPointerException -
map.put(OtherEnum.VALUE, "x")→ 抛ClassCastException - 允许 value 为
null,但get(key)返回null时,无法区分“键不存在”还是“值设为 null”;需要用containsKey(key)明确判断
遍历天然有序,但别当成业务逻辑依赖
迭代顺序严格按枚举声明顺序(即 ordinal() 升序),这是数组下标遍历的自然结果,不是额外排序。
- 适合生成配置下拉、状态流转说明等需要稳定顺序的场景
- 如果代码隐含“第一个 key 是默认值”,后来在枚举开头加了新常量,逻辑就偏了
- 不能替代
TreeMap做自定义排序——EnumMap 不支持Comparator,也没有sortedKeySet()
集合视图是只读快照,结构性修改要小心
keySet()、entrySet()、values() 返回的是视图,不是副本:
-
keySet().add(...)或values().clear()→ 抛UnsupportedOperationException -
keySet().remove(key)是合法的,等价于map.remove(key) - 若需可变集合,得显式复制:
new ArrayList(map.keySet()) - 迭代中混用
put()和keySet().iterator(),可能跳过新 entry 或重复遍历旧 entry
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











