enummap 专为枚举设计,以 ordinal() 为索引实现 o(1) 存取、内存紧凑、顺序固定;需传入枚举 class,不支持 null 键或非枚举类型,新增枚举常量后需重建实例。

Java 中枚举类天然适合作为 EnumMap 的键,因为 EnumMap 是专为枚举类型设计的高性能映射实现,内部用数组存储,不依赖哈希,也不允许 null 键。
为什么用 EnumMap 而不是 HashMap?
EnumMap 是 JDK 提供的专用 Map 实现,它要求键必须是枚举类型,并在内部以枚举的 ordinal() 值为索引直接存取,时间复杂度 O(1),内存更紧凑,且线程不安全但比 HashMap 更快、更安全(不会因枚举实例变化导致哈希冲突或失效)。
注意:EnumMap 不接受 null 键,也不支持非枚举类型;它的迭代顺序严格按枚举常量声明顺序,不是插入顺序,也不是自然顺序。
基础用法:声明、初始化与存取
假设有一个表示订单状态的枚举:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
enum OrderStatus {
PENDING, PROCESSING, SHIPPED, DELIVERED, CANCELLED
}
配合 EnumMap 使用:
- 声明时需指定枚举类型:
EnumMap<orderstatus string> statusDesc = new EnumMap(OrderStatus.class);</orderstatus> - 插入值:
statusDesc.put(OrderStatus.PENDING, "等待支付"); - 获取值:
String desc = statusDesc.get(OrderStatus.SHIPPED); // 返回对应描述 - 遍历推荐用 entrySet(),顺序即枚举声明顺序:
for (var entry : statusDesc.entrySet()) { ... }
配合枚举自带属性增强可维护性
枚举本身可以封装数据,再用 EnumMap 映射到其他结构,避免硬编码重复。例如让每个枚举值携带 HTTP 状态码和默认消息:
enum ApiCode {
SUCCESS(200, "操作成功"),
NOT_FOUND(404, "资源不存在"),
BAD_REQUEST(400, "请求参数错误");
final int code;
final String message;
ApiCode(int code, String message) {
this.code = code;
this.message = message;
}
}
此时可以用 EnumMap 映射到自定义处理器:
EnumMap<apicode biconsumer httpservletresponse>> handlerMap = new EnumMap(ApiCode.class);</apicode>handlerMap.put(ApiCode.SUCCESS, (msg, resp) -> resp.setStatus(200));- 调用时直接
handlerMap.get(code).accept("ok", response);
这样既保持枚举语义清晰,又通过 EnumMap 实现快速分发,逻辑解耦且不易出错。
注意事项与常见陷阱
- 构造
EnumMap必须传入枚举的Class对象,不能用泛型推断(如new EnumMap()会编译失败) - 不能 put 非该枚举类型的实例(哪怕同名不同类也不行),否则抛
ClassCastException - 如果枚举新增常量,已存在的
EnumMap不会自动扩容——但其实无需担心,EnumMap在创建时就根据枚举values().length分配了固定大小数组,新增枚举后需重启或重建 map 实例 - 不支持并发写入,多线程修改需外部同步(如用
Collections.synchronizedMap()包装,但会损失性能优势)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










