Java的HashMap明确支持null键,通过hash()中key==null?0:...分支实现;所有null键哈希值为0,统一映射到table[0],用==判断唯一性,get(null)直查table[0]但返回null无法区分“键不存在”与“值为null”,须用containsKey(null)判断存在性。

Java 的 HashMap 允许键为 null,不是“侥幸没崩”,而是设计上就做了明确支持——核心在于哈希计算逻辑的特殊分支处理。
哈希值固定为 0,不调用 hashCode()
当传入 null 作为键时,HashMap 不会执行 key.hashCode()(那会直接抛 NullPointerException),而是走专用路径:
static final int hash(Object key) { return (key == null) ? 0 : (key.hashCode() ^ (key.hashCode() >>> 16)); }- 所有
null键的哈希值统一为0 - 因此它们必然被映射到数组索引
0的桶(即table[0])中
只允许一个 null 键,靠 == 判断唯一性
因为所有 null 键都落在同一个桶里,后续插入时,HashMap 在遍历该桶节点时,用 key == null(不是 equals)来判断是否已存在 null 键:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
-
put(null, "a")→ 存入table[0]链表/红黑树头部 -
put(null, "b")→ 找到已有null键节点,直接覆盖其 value - 不会新增节点,也不会重复存储
get(null) 怎么查?跳过哈希,直奔 table[0]
get(null) 不走通用哈希查找流程,而是直接进入专用分支:
立即学习“Java免费学习笔记(深入)”;
- 检查
key == null,跳过哈希计算 - 定位到
table[0],遍历其中所有节点 - 逐个用
e.key == null判断匹配(不调equals、不调compareTo) - 找到则返回对应
value;没找到则返回null
关键陷阱:get(null) 返回 null 无法区分“不存在”和“值为 null”
这是最易出错的地方:
-
map.put(null, null);→ 键存在,值也是null -
map.get(null) == null→ 真实发生,但你不知道是哪种情况 - ❌ 错误写法:
if (map.get(null) == null) { /* 认为键不存在 */ } - ✅ 正确做法:
if (map.containsKey(null)) { /* 键确实存在 */ },再调get(null)取值 - 若业务上必须区分状态,建议避免用
null当键,改用哨兵对象如NO_KEY

















