在集合中哪些可以为null,哪些不能为null;Java 集合中 null 值允许情况总结与记忆技巧

Java 集合中 null 值允许情况总结与记忆技巧

一、核心集合对 null 的支持情况

集合类型Key 是否可为 nullValue 是否可为 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);
});

五、总结表(速记版)

集合类型KeyValue记忆口诀
HashMap哈林可以
LinkedHashMap哈林可以
TreeMap树并不行(Tree不行)
Hashtable老古董
ConcurrentHashMap树并不行(Concurrent不行)
HashSet-Hash 随意
TreeSet-Tree 挑剔
ArrayList-列表宽容
ArrayDeque-队列严格

掌握这些规则和记忆技巧,面试时再也不用担心 null 值问题!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

步行cgn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值