0

0

Java中的EnumMap为什么比HashMap快_数组直接寻址与枚举常量的强绑定

P粉602998670

P粉602998670

发布时间:2026-03-17 09:17:03

|

204人浏览过

|

来源于php中文网

原创

EnumMap 底层是基于枚举 ordinal() 的 Object[] 数组,O(1) 访问无哈希开销;不允许 null key,泛型强制 K extends Enum<K>;空间固定、遍历有序、性能优于 HashMap,适用于封闭枚举场景。

java中的enummap为什么比hashmap快_数组直接寻址与枚举常量的强绑定

EnumMap 的底层是数组,不是哈希表

EnumMap 不走 hashCode() + 拉链/红黑树那一套,它内部用的是 Object[],索引直接对应枚举常量的 ordinal() 值。比如 Color.RED.ordinal() == 0,那它的值就存在数组第 0 位——纯数组访问,O(1) 且无哈希计算开销。

常见错误现象:NullPointerException 出现在 put 一个 null 枚举实例时(EnumMap 不允许 key 为 null);或者误以为能存非声明枚举类型的值,结果抛 ClassCastException

  • 必须用编译期已知的枚举类构造,运行时不能换;new EnumMap<SomeEnum>(OtherEnum.class) 会直接报错
  • 构造时传入的 Class 对象必须是具体枚举类型,不能是其父类或接口
  • 数组长度 = 枚举类中常量个数,所以空间占用固定、可预测,没有扩容逻辑

EnumMap 只接受一种枚举类型作为 key

它的泛型约束是 <K extends Enum<K>>,强制 key 必须是某个具体枚举类的实例,且所有 key 都得来自同一个枚举类。这带来两个实际影响:类型安全强,但灵活性差。

使用场景:配置开关、状态映射、协议码转义等 key 集合完全封闭且已知的场合。比如 HTTP 状态码映射到描述字符串,用 EnumMap<HttpStatus, String> 就比 HashMap<Integer, String> 更安全、更快。

立即学习Java免费学习笔记(深入)”;

  • 不能混用不同枚举类型,哪怕它们有相同 name 或 ordinal;enum A { X };enum B { X } 是完全不兼容的
  • 如果枚举类后期新增常量,EnumMap 实例不受影响,但新常量的默认值是 null(除非显式 put)
  • 遍历顺序严格按枚举常量声明顺序,不是插入顺序,也不是哈希顺序

为什么 put/get 比 HashMap 快?少三步运算

HashMap 的 put(K,V) 至少要算 hash、找桶、处理冲突;EnumMap 的 put(K,V) 只做三件事:校验 key 非 null、取 key.ordinal()、数组赋值。没有 hash 计算,没有位运算取模,没有节点对象创建。

VanceAI Image Resizer
VanceAI Image Resizer

VanceAI推出的在线图片尺寸调整工具

下载

性能差异在小数据量下特别明显。实测 10 个键值对的读写,EnumMap 通常比 HashMap 快 2–3 倍;即使到几百个,优势仍在,只是差距收窄。

  • 没有装箱开销:枚举实例本身就是对象引用,不像 HashMap<Integer, V> 要频繁 Integer.valueOf()
  • JVM 对 ordinal() 优化极好,基本等价于字段读取,比调用任意其他方法都轻
  • 数组访问天然局部性好,CPU 缓存友好;HashMap 的桶数组+链表/树结构更容易造成缓存不命中

别在 EnumMap 里存大量 null 值

虽然 EnumMap 内部数组大小固定,但如果枚举类有 100 个常量,你只 put 了其中 5 个,剩下 95 个位置都是 null——内存没浪费,但语义上容易误导。更麻烦的是,containsKey(k) 返回 false 时,你无法区分“真没存过”还是“存过但 value 是 null”。

这是 EnumMap 和 HashMap 的关键语义差异:HashMap 允许 put(k, null) 并保留该记录;EnumMap 也允许,但 get(k) 返回 null 时,你必须额外调用 containsKey(k) 才能确认是否存在。

  • 如果业务逻辑依赖 “null 值有意义”,EnumMap 不适合;改用 HashMap 或包装一层
  • size() 返回的是非-null value 的数量,不是数组长度
  • 序列化时只保存非-null 条目,反序列化后缺失的索引位置仍是 null

真正要注意的,是把 EnumMap 当成“带类型约束的紧凑数组映射”,而不是“更快的 HashMap 替代品”。一旦 key 不确定来自哪个枚举,或者需要动态扩展 key 集合,它就不再适用。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1071

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

255

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1153

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1570

2023.10.24

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1570

2023.10.24

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1570

2023.10.24

chatgpt使用指南
chatgpt使用指南

本专题整合了chatgpt使用教程、新手使用说明等等相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.5万人学习

C# 教程
C# 教程

共94课时 | 11.5万人学习

Java 教程
Java 教程

共578课时 | 83.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号