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

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

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

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

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

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

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

1.HashMap和ConcurrentHashMap的区别

HashMap 和 ConcurrentHashMap 在对待 null 的态度上是不同的,在 Java 中,HashMap 是允许 key 和 value 值都为 null 的,如下代码所示:Rej28资讯网——每日最新资讯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");}

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

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

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

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

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

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

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

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

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

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

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

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

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

2.为什么不能插入null?

如果我们查看 ConcurrentHashMap 的源码,就能发现为什么 ConcurrentHashMap 不能插入 null 了,以下是 ConcurrentHashMap 添加元素时的部分核心源码:Rej28资讯网——每日最新资讯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 的根本原因了,因为源码就是这样设计的。Rej28资讯网——每日最新资讯28at.com

3.更深层次的原因

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

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

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

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

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

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

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

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

(2)可证伪的HashMap

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

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

(3)不可证伪的ConcurrentHashMap

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

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

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

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

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

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

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

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

标签:
  • 热门焦点
  • 5月iOS设备性能榜:M1 M2依旧是榜单前五

    和上个月一样,没有新品发布的iOS设备性能榜的上榜设备并没有什么更替,仅仅只有跑分变化而产生的排名变动,刚刚开始的苹果WWDC2023,推出的产品也依旧是新款Mac Pro、新款Mac Stu
  • 5月安卓手机好评榜:魅族20 Pro夺冠

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年5月1日至5月31日,仅限国内市场。第一名:魅族20 Pro好评率:97.50%不得不感慨魅族老品牌还
  • Flowable工作流引擎的科普与实践

    一.引言当我们在日常工作和业务中需要进行各种审批流程时,可能会面临一系列技术和业务上的挑战。手动处理这些审批流程可能会导致开发成本的增加以及业务复杂度的上升。在这
  • 之家push系统迭代之路

    前言在这个信息爆炸的互联网时代,能够及时准确获取信息是当今社会要解决的关键问题之一。随着之家用户体量和内容规模的不断增大,传统的靠"主动拉"获取信息的方式已不能满足用
  • 虚拟键盘 API 的妙用

    你是否在遇到过这样的问题:移动设备上有一个固定元素,当激活虚拟键盘时,该元素被隐藏在了键盘下方?多年来,这一直是 Web 上的默认行为,在本文中,我们将探讨这个问题、为什么会发生
  • 微软邀请 Microsoft 365 商业用户,测试视频编辑器 Clipchamp

    8 月 1 日消息,微软近日宣布即将面向 Microsoft 365 商业用户,开放 Clipchamp 应用,邀请用户通过该应用来编辑视频。微软于 2021 年收购 Clipchamp,随后开始逐步整合到 Microsof
  • 零售大模型“干中学”,攀爬数字化珠峰

    文/侯煜编辑/cc来源/华尔街科技眼对于绝大多数登山爱好者而言,攀爬珠穆朗玛峰可谓终极目标。攀登珠峰的商业路线有两条,一是尼泊尔境内的南坡路线,一是中国境内的北坡路线。相
  • Temu起诉SHEIN,跨境电商战事升级

    来源 | 伯虎财经(bohuFN)作者 | 陈平安日前据外媒报道,拼多多旗下跨境电商平台Temu正对竞争对手SHEIN提起新诉讼,诉状称Shein&ldquo;利用市场支配力量强迫服装厂商与之签订独家
  • 当家的盒马,加速谋生

    来源 | 价值星球Planet作者 | 归去来自己&ldquo;当家&rdquo;的盒马,开始加速谋生了。据盒马官微消息,盒马计划今年开放生鲜供应链,将其生鲜商品送往食堂。目前,盒马在上海已经与
Top