HashMap、ConcurrentHashMap、HashTable和TreeMap 为啥有的支持key支持null,有的value支持null?

HashMap、ConcurrentHashMap、HashTable和TreeMap相信小伙伴们都不陌生,他们之间的区别在面试中经常会被问道。key/value能不能是null,是我们必答的一条,相信你们也都能说出来。但继续向下追问一下,为啥有的key可以是null,有的value可以是null,可能就会让面试场面尬住了…
类型key可以为nullvalue可以为null
HashMaptruetrue
HashTablefalsefalse
ConcurrentHashMapfalsefalse
TreeMapfalsetrue
上表给出了key/value是否可以为null的情况。

1、为啥key不能为null?
HashMap可以为null:
Oracle公司的技术负责人Stuart Marks说:将允许空键的决定视为最初犯的错误。我们可以看出HashMap允许key为null只是一个意外…
HashTable、ConcurrentHashMap、TreeMap不可以为null:
如下代码所示,每个对象的hash值是根据对象的hashcode码计算出来的。如果对象为null,调用它的hashCode()方法一定会抛出空指针异常。

 static final int hash(Object key) {
        int h;
        // h >>> 16 无符号右移16位
        // 将前16位与后16位进行异或作为hash值,让对象更加分散的入桶。
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

2、为啥value不能为null?
这里我们将map分为两类,一类是并发的ConcurrentHashMap/HashTable等,另一类是非并发的HashMap/TreeMap.
线程不安全map,它的Value是可以为null的。以HashMap为例子,为啥允许为null:

HashMap<String,String> map = new HashMap<String,String>();
Object result = map.get("xiaohong"); ==>因为不存在xiaohong这个值,所以返回的是null。这时候就存在歧义了,返回的null代表的是entry的value为null,还是压根就没有这个entry。为了区分,我们可以继续判断。
bool status = map.containsKey("xiaohong") ⇒ 这时候返回true说明,result代表的是entry的value值为null;反之,则entry不存在;

使用contains方法我们就可以推断出get方法返回的null代表的是啥意思。
下面分析,并发map为啥value不能为null:

        ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
        Object result = map.get("xiaohong");  // 因为不存在xiaohong这个值,所以返回的是null。这时候就存在歧义了,返回的null代表的是entry的value为null,还是压根就没有这个entry。为了区分,我们尝试继续判断
        
        ####################其他线程操作map   开始####################
        map.put("xiaohong",”sno2020190“);
        ####################其他线程操作map    结束####################

        bool status = map.containsKey("xiaohong") ==> 返回值为true, 我们会误认为result为null是由于entry中的value为nul造成的。这时候会认为,键值是xiaohong的value为null,这就出错了。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值