• 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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

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

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

            ConcurrentHashMap 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,这就出错了。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    docker容器中没有vi编辑器的解决办法
    C++ 类型转换
    Haproxy实现七层负载均衡
    关于docker无法正常下载镜像的问题
    Ubuntu本地快速搭建web小游戏网站,公网用户远程访问【内网穿透】
    相机卡格式化了还能恢复吗?答案在这!(附带恢复教程)
    Prometheus完整安装
    wireshark——解密加密报文
    Linus Torvalds接受来自微软的Linux Hyper-V升级
    pycharm中个人编程时常用到的快捷键
  • 原文地址:https://blog.csdn.net/qq_29012499/article/details/128119969