HashMap允许一个null键,强制存入table[0],不参与哈希计算;null值可任意数量存放,无限制。

Java 中 HashMap 对 null 键 的处理是明确且固定的:它只允许一个 null 键,并将其强制存入哈希表数组的索引 0 位置,不参与常规哈希计算;而 null 值 则无限制,可任意数量、任意位置存放。
Null 键怎么存?走特殊通道,不哈希
调用 put(null, value) 时:
- HashMap 先检测 key == null,一旦为真,直接跳过哈希计算和扰动函数;
- 不调用
key.hashCode()(否则会空指针); - 也不执行
hash & (table.length - 1)定位; - 而是硬编码写入 table[0] —— 即底层数组的第一个桶;
- 如果 table[0] 已有元素(比如另一个 null 键或普通键),就按链表或红黑树逻辑比较 key:null 与 null 用 == 判定相等,所以后续 put(null, newValue) 会覆盖旧值。
Null 值怎么存?完全自由,无额外约束
null 作为 value 是被完全允许的,且不限次数:
- 可以和任意非 null 键搭配,如
map.put("a", null)、map.put(123, null); - 也可以和 null 键共存:
map.put(null, null)是合法操作; - 存储过程与非 null 值完全一致:算哈希 → 定桶 → 插入/覆盖,只是 value 字段被设为
null。
取 null 键或 null 值时要注意什么?
读取行为容易引发误判:
立即学习“Java免费学习笔记(深入)”;
-
get(null)会去查 table[0],返回对应 value(可能是null,也可能不是); - 但
get(key)返回null并不能说明“key 不存在”——它可能表示:key 存在但 value 为 null,或 key 根本不存在; - 因此判断存在性必须用
containsKey(null)或containsKey(k),而不是依赖get(k) == null。
为什么设计成这样?
这种机制兼顾了简洁性与实用性:
- 避免对 null 调用 hashCode() 导致 NullPointerException;
- 把 null 键收束到固定位置,简化查找路径,保持 O(1) 平均性能;
- 不对 value 做限制,让使用者能表达“有这个键,但暂无值”的语义。


















