当前位置:首页 > 科技  > 软件

高德面试:为什么Map不能插入Null?

来源: 责编: 时间:2024-06-06 17:43:21 274观看
导读在 Java 中,Map 是属于 java.util 包下的一个接口(interface),所以说“为什么 Map 不能插入 null?”这个问题本身问的不严谨。Map 部分类关系图如下:所以,这里面试官其实想问的是:为什么 ConcurrentHashMap 不能插入 null?1.Ha

Y7b28资讯网——每日最新资讯28at.com

在 Java 中,Map 是属于 java.util 包下的一个接口(interface),所以说“为什么 Map 不能插入 null?”这个问题本身问的不严谨。Map 部分类关系图如下:Y7b28资讯网——每日最新资讯28at.com

Y7b28资讯网——每日最新资讯28at.com

所以,这里面试官其实想问的是:为什么 ConcurrentHashMap 不能插入 null?Y7b28资讯网——每日最新资讯28at.com

1.HashMap和ConcurrentHashMap的区别

HashMap 和 ConcurrentHashMap 在对待 null 的态度上是不同的,在 Java 中,HashMap 是允许 key 和 value 值都为 null 的,如下代码所示:Y7b28资讯网——每日最新资讯28at.com

HashMap<String, Object> map = new HashMap();map.put(null, null);if (map.containsKey(null)) {    System.out.println("存在 null");} else {    System.out.println("不存在 null");}

以上程序的执行结果如下:Y7b28资讯网——每日最新资讯28at.com

存在 nullY7b28资讯网——每日最新资讯28at.com

从上述结果可以看出,HashMap 是允许  key 和 value 值都为 null 的。Y7b28资讯网——每日最新资讯28at.com

但 ConcurrentHashMap 就不同了,它不但 key 不能为 null,而且 value 也不能为 null,如以下代码所示:Y7b28资讯网——每日最新资讯28at.com

ConcurrentHashMap<String, String> concurrentHashMap = new ConcurrentHashMap();concurrentHashMap.put(null, "javacn.site");System.out.println(concurrentHashMap.get(null));

在运行以上程序时就会报错,如下图所示:Y7b28资讯网——每日最新资讯28at.com

Y7b28资讯网——每日最新资讯28at.com

当然,当你为 ConcurrentHashMap 的 value 值设置 null 时也会报错,如下代码所示:Y7b28资讯网——每日最新资讯28at.com

String key = "www.avacn.site";ConcurrentHashMap<String, String> concurrentHashMap = new ConcurrentHashMap();concurrentHashMap.put(key, null);System.out.println(concurrentHashMap.get(key));

在运行以上程序时就会报错,如下图所示:Y7b28资讯网——每日最新资讯28at.com

Y7b28资讯网——每日最新资讯28at.com

因此,我们可以得出结论:Y7b28资讯网——每日最新资讯28at.com

  • 在 HashMap 中,key 和 value 值都可以为 null。
  • 在 ConcurrentHashMap 中,key 或者是 value 值都不能为 null。

2.为什么不能插入null?

如果我们查看 ConcurrentHashMap 的源码,就能发现为什么 ConcurrentHashMap 不能插入 null 了,以下是 ConcurrentHashMap 添加元素时的部分核心源码:Y7b28资讯网——每日最新资讯28at.com

// 添加 key 和 valuepublic V put(K key, V value) {    return putVal(key, value, false);}final V putVal(K key, V value, boolean onlyIfAbsent) {    // 如果 key 或 value 为 null 的话直接抛出空指针异常    if (key == null || value == null) throw new NullPointerException();    int hash = spread(key.hashCode());    int binCount = 0;    // 忽略其他代码......}

从上述 ConcurrentHashMap 添加元素的第一行源码就可以看出,当 key 或 value 为 null 时,会直接抛出空指针异常,这就是 ConcurrentHashMap 之所以不能插入 null 的根本原因了,因为源码就是这样设计的。Y7b28资讯网——每日最新资讯28at.com

3.更深层次的原因

那么问题来了,为什么 ConcurrentHashMap 的实现源码中,不允许为 key 或者是 value 设置 null 呢?Y7b28资讯网——每日最新资讯28at.com

这就要从 ConcurrentHashMap 的使用场景说起了,在 Java 中,ConcurrentHashMap 是用于并发环境中执行的线程安全的容器,而 HashMap 是用于单线程环境下执行的非线程安全的容器,而并发环境下的运行更复杂,如果我们允许 ConcurrentHashMap 的 key 或者是 value 为 null 的情况下,就会存在经典的“二义性问题”。Y7b28资讯网——每日最新资讯28at.com

(1)什么是二义性问题?

所谓的二义性问题指的是代码或表达式存在多种理解或解释,导致程序的含义不明确或模糊。Y7b28资讯网——每日最新资讯28at.com

以 ConcurrentHashMap 不允许为 null 的二义性问题来说,null 其实有以下两层含义:Y7b28资讯网——每日最新资讯28at.com

  • 这个值本身设置的是 null,null 在这里表示的是一种具体的“null”值状态。
  • null 还表示“没有”的意思,因为没有设置,所以啥也没有。

所以,如果 ConcurrentHashMap 允许插入 null 值,那么就会存在二义性问题。Y7b28资讯网——每日最新资讯28at.com

那就有同学会问了,为什么 HashMap 允许插入 null,它就不怕有二义性问题吗?Y7b28资讯网——每日最新资讯28at.com

(2)可证伪的HashMap

HashMap 之所以不怕二义性问题的原因是,HashMap 的设计是给单线程使用的,而单线程下的二义性问题是能被证明真伪的,所以也就不存在二义性问题了(能被证明的问题就不是二义性问题)Y7b28资讯网——每日最新资讯28at.com

例如,当我们给 HashMap 的 key 设置为 null 时,我们可以通过 hashMap.containsKey(key) 的方法来区分这个 null 值到底是存入的 null?还是压根不存在的 null?这样二义性问题就得到了解决,所以 HashMap 的二义性问题可被证明真伪,所以就不怕二义性问题,因此也就可以给 key 或者 value 设置 null 了。Y7b28资讯网——每日最新资讯28at.com

(3)不可证伪的ConcurrentHashMap

而 ConcurrentHashMap 就不一样了,因为 ConcurrentHashMap 是设计在多线程下使用的,而多线程下的二义性问题是不能被证明真伪的,所以二义性问题是真实存在的。Y7b28资讯网——每日最新资讯28at.com

因为在你在证明二义性问题的同时,可能会有另一个线程影响你的执行结果,所以它的二义性问题就一直存在。Y7b28资讯网——每日最新资讯28at.com

例如,当 ConcurrentHashMap 未设置 key 为 null 时,会有这样一个场景,当一个线程 A 调用了 concurrentHashMap.containsKey(key),我们期望返回的结果是 false,但在我们调用 concurrentHashMap.containsKey(key) 之后,未返回结果之前,线程 B 又调用了 concurrentHashMap.put(key,null) 存入了 null 值,那么线程 A 最终返回的结果就是 true 了,这个结果和我们之前预想的 false 完全不一样,这就是不能被证伪的二义性问题。Y7b28资讯网——每日最新资讯28at.com

所以说,多线程的执行比较复杂,在多线程下 null 的二义性问题是不能被证明真伪的(因为在一个线程执行验证时,可能会有另一个线程改动结果,造成结果不准确),所以 ConcurrentHashMap 为了避免这个二义性问题,所以就在源码中禁用了 null 值作为 key 或 value。Y7b28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-92476-0.html高德面试:为什么Map不能插入Null?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 转转回收业务策略中心的实践

下一篇: 通过Spring Boot结合实时流媒体技术对考试过程进行实时监控

标签:
  • 热门焦点
  • 把LangChain跑起来的三个方法

    使用LangChain开发LLM应用时,需要机器进行GLM部署,好多同学第一步就被劝退了,那么如何绕过这个步骤先学习LLM模型的应用,对Langchain进行快速上手?本片讲解3个把LangChain跑起来
  • 三言两语说透设计模式的艺术-单例模式

    写在前面单例模式是一种常用的软件设计模式,它所创建的对象只有一个实例,且该实例易于被外界访问。单例对象由于只有一个实例,所以它可以方便地被系统中的其他对象共享,从而减少
  • 量化指标是与非:挽救被量化指标扼杀的技术团队

    作者 | 刘新翠整理 | 徐杰承本文整理自快狗打车技术总监刘新翠在WOT2023大会上的主题分享,更多精彩内容及现场PPT,请关注51CTO技术栈公众号,发消息【WOT2023PPT】即可直接领取
  • 让我们一起聊聊文件的操作

    文件【1】文件是什么?文件是保存数据的地方,是数据源的一种,比如大家经常使用的word文档、txt文件、excel文件、jpg文件...都是文件。文件最主要的作用就是保存数据,它既可以保
  • 三万字盘点 Spring 九大核心基础功能

    大家好,我是三友~~今天来跟大家聊一聊Spring的9大核心基础功能。话不多说,先上目录:图片友情提示,本文过长,建议收藏,嘿嘿嘿!一、资源管理资源管理是Spring的一个核心的基础功能,不
  • 本地生活这块肥肉,拼多多也想吃一口

    出品/壹览商业 作者/李彦编辑/木鱼拼多多也看上本地生活这块蛋糕了。近期,拼多多在App首页&ldquo;充值中心&rdquo;入口上线了本机生活界面。壹览商业发现,该界面目前主要
  • 自律,给不了Keep自由!

    来源 | 互联网品牌官作者 | 李大为编排 | 又耳 审核 | 谷晓辉自律能不能给用户自由暂时不好说,但大概率不能给Keep自由。近日,全球最大的在线健身平台Keep正式登陆港交所,努力
  • Windows 11发布,微软一改往常对老机型开放的态度

    距离 Windows 11 发布已经过去一周,在过去一周里,很多数码爱好者围绕其对 Android 应用的支持、对老机型的升级问题展开了激烈讨论。与以往不同的是,在这次大
  • 上海举办人工智能大会活动,建设人工智能新高地

    人工智能大会在上海浦江两岸隆重拉开帷幕,人工智能新技术、新产品、新应用、新理念集中亮相。8月30日晚,作为大会的特色活动之一的上海人工智能发展盛典人工
Top