在集合中哪些可以为null,哪些不能为null;Java 集合中 null 值允许情况总结与记忆技巧
Java 集合中 null 值允许情况总结与记忆技巧
一、核心集合对 null 的支持情况
集合类型 | Key 是否可为 null | Value 是否可为 null | 原因/备注 |
---|---|---|---|
HashMap | ✅ 是 | ✅ 是 | 对 null key 有特殊处理(存放在数组第 0 个位置) |
LinkedHashMap | ✅ 是 | ✅ 是 | 继承自 HashMap |
TreeMap | ❌ 否 | ✅ 是 | 依赖 Comparator/Comparable,可能抛 NullPointerException
|
Hashtable | ❌ 否 | ❌ 否 | 设计较早,未做 null 处理(直接抛 NullPointerException ) |
ConcurrentHashMap | ❌ 否 | ❌ 否 | 并发场景下 null 会歧义(如 get(key)返回null时无法区分是不存在还是值为null) |
HashSet | ✅ 是 | - | 底层是 HashMap,value 固定为 PRESENT 对象 |
TreeSet | ❌ 否 | - | 底层是 TreeMap |
ArrayList | - | ✅ 是 | 列表允许存储 null |
LinkedList | - | ✅ 是 | 同 ArrayList |
ArrayDeque | - | ❌ 否 | 作为队列/栈使用时,null 会干扰 poll() 等方法语义 |
二、记忆技巧(口诀)
1. Map 系列记忆法
"哈林可以,树并不行"
哈(HashMap)、林(LinkedHashMap):允许 null key 和 null value
树(TreeMap)、并(ConcurrentHashMap):不允许 null key
Hashtable:老古董,什么都不让用(联想:老顽固)
2. Set 系列记忆法
"Hash 随意,Tree 挑剔"
HashSet:允许 null(因为底层是 HashMap)
TreeSet:不允许 null(因为底层是 TreeMap)
3. List/Queue 记忆法
"列表宽容,队列严格"
ArrayList/LinkedList:允许 null
ArrayDeque:不允许 null(避免 poll() 歧义)
三、技术原因深度解析
1. 为什么 HashMap 允许 null?
-
特殊处理:将 null key 的哈希值固定为 0,存储在数组第 0 个桶。
-
代码示例(HashMap 的 put 方法):
java
if (key == null) {
return putForNullKey(value); // 特殊处理
}
2. 为什么 TreeMap 不允许 null key?
-
排序依赖:必须调用
compareTo()
或compare()
,null 无法比较。 -
代码示例:
java
// 如果 comparator 为 null,使用自然排序
Comparator<? super K> cpr = comparator;
if (cpr == null) {
Comparable<? super K> k = (Comparable<? super K>) key; // 这里可能抛 NPE
}
3. 为什么 ConcurrentHashMap 完全禁止 null?
-
并发歧义:
-
如果允许 null value,无法区分
map.get(key)==null
是"不存在该key"还是"该key的值为null"。 -
作者 Doug Lea 的解释:"在非并发Map中,可以通过containsKey检查,但并发场景下检查与操作不是原子的"。
-
四、面试高频问题
1. HashMap 如何处理 null key?
-
存储在数组第 0 个桶(
table[0]
),哈希值固定为 0。
2. 哪些集合的迭代器可能抛 NullPointerException?
-
TreeMap/TreeSet:如果元素未实现
Comparable
或Comparator
未处理 null。
3. 如何让 TreeMap 支持 null key?
-
自定义
Comparator
处理 null:java
TreeMap<String, Integer> map = new TreeMap<>((a, b) -> {
if (a == null) return -1; // 定义 null 的排序规则
if (b == null) return 1;
return a.compareTo(b);
});
五、总结表(速记版)
集合类型 | Key | Value | 记忆口诀 |
---|---|---|---|
HashMap | ✅ | ✅ | 哈林可以 |
LinkedHashMap | ✅ | ✅ | 哈林可以 |
TreeMap | ❌ | ✅ | 树并不行(Tree不行) |
Hashtable | ❌ | ❌ | 老古董 |
ConcurrentHashMap | ❌ | ❌ | 树并不行(Concurrent不行) |
HashSet | ✅ | - | Hash 随意 |
TreeSet | ❌ | - | Tree 挑剔 |
ArrayList | - | ✅ | 列表宽容 |
ArrayDeque | - | ❌ | 队列严格 |
掌握这些规则和记忆技巧,面试时再也不用担心 null 值问题!
上一篇: 几秒钟就充满电!科学
下一篇: 暂无数据