HashMap允许一个null键(固定存于bucket[0],覆盖不新增)和任意多个null值(无位置限制);判断键存在且值非空需结合containsKey()与get()或使用getOrDefault()。

Java 中的 HashMap 允许一个 null 键和任意多个 null 值,但它们的存储机制完全不同,理解这点对避免空指针和逻辑误判很关键。
null 键的存储位置固定在 bucket[0]
HashMap 对 null 键做了特殊处理:它不调用 hashCode() 方法,而是直接把整个键值对存入哈希表数组的第 0 号桶(即 table[0])中。这意味着:
- 无论你 put 多少次
put(null, "a")、put(null, "b"),最终只保留最后一次的值,“null键”在逻辑上永远只有一个; -
get(null)、remove(null)、containsKey(null)这些操作都跳过哈希计算,直奔table[0]查找或修改; - 所有语义上不同的 null 引用(比如
String s = null;和Integer i = null;)在 HashMap 中都被视为同一个键,无法区分。
null 值可存在任意键下,无位置限制
null 值本身没有特殊存储逻辑,只要键合法,值就可以是 null。例如:
-
map.put("name", null);合法,该键值对会按正常哈希流程定位到某个 bucket(比如table[5]),然后插入链表或红黑树节点; - 多个不同键可以同时映射到
null值,互不影响; - 值为
null的节点结构和其他节点完全一致,只是value字段为null。
怎么安全判断“键存在且值非空”
仅靠 map.get(key) == null 无法区分两种情况:键根本不存在,或者键存在但值就是 null。推荐以下方式:
立即学习“Java免费学习笔记(深入)”;
- 先调用
map.containsKey(key)确认键存在,再用map.get(key) != null判断值非空; - 使用
map.getOrDefault(key, sentinel),传入一个明确的默认值(如 new Object() 或 Optional.empty()),避免null模糊性; - 函数式写法:
Optional.ofNullable(map.get(key)).isPresent()或链式处理后续逻辑。
对比其他 Map 实现
不是所有 Map 都支持 null 键/值:
-
HashMap / LinkedHashMap:支持一个
null键、多个null值; -
ConcurrentHashMap / Hashtable:禁止
null键和null值,插入时直接抛NullPointerException; -
TreeMap:不允许
null键(因依赖compareTo()或compare(),null 会导致 NPE),但允许null值(除非 value 本身参与比较)。


















