日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

高德面試:為什么Map不能插入Null?

來源: 責(zé)編: 時間:2024-06-06 17:43:21 148觀看
導(dǎo)讀在 Java 中,Map 是屬于 java.util 包下的一個接口(interface),所以說“為什么 Map 不能插入 null?”這個問題本身問的不嚴謹。Map 部分類關(guān)系圖如下:所以,這里面試官其實想問的是:為什么 ConcurrentHashMap 不能插入 null?1.Ha

qOv28資訊網(wǎng)——每日最新資訊28at.com

在 Java 中,Map 是屬于 java.util 包下的一個接口(interface),所以說“為什么 Map 不能插入 null?”這個問題本身問的不嚴謹。Map 部分類關(guān)系圖如下:qOv28資訊網(wǎng)——每日最新資訊28at.com

qOv28資訊網(wǎng)——每日最新資訊28at.com

所以,這里面試官其實想問的是:為什么 ConcurrentHashMap 不能插入 null?qOv28資訊網(wǎng)——每日最新資訊28at.com

1.HashMap和ConcurrentHashMap的區(qū)別

HashMap 和 ConcurrentHashMap 在對待 null 的態(tài)度上是不同的,在 Java 中,HashMap 是允許 key 和 value 值都為 null 的,如下代碼所示:qOv28資訊網(wǎng)——每日最新資訊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");}

以上程序的執(zhí)行結(jié)果如下:qOv28資訊網(wǎng)——每日最新資訊28at.com

存在 nullqOv28資訊網(wǎng)——每日最新資訊28at.com

從上述結(jié)果可以看出,HashMap 是允許  key 和 value 值都為 null 的。qOv28資訊網(wǎng)——每日最新資訊28at.com

但 ConcurrentHashMap 就不同了,它不但 key 不能為 null,而且 value 也不能為 null,如以下代碼所示:qOv28資訊網(wǎng)——每日最新資訊28at.com

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

在運行以上程序時就會報錯,如下圖所示:qOv28資訊網(wǎng)——每日最新資訊28at.com

qOv28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)然,當(dāng)你為 ConcurrentHashMap 的 value 值設(shè)置 null 時也會報錯,如下代碼所示:qOv28資訊網(wǎng)——每日最新資訊28at.com

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

在運行以上程序時就會報錯,如下圖所示:qOv28資訊網(wǎng)——每日最新資訊28at.com

qOv28資訊網(wǎng)——每日最新資訊28at.com

因此,我們可以得出結(jié)論:qOv28資訊網(wǎng)——每日最新資訊28at.com

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

2.為什么不能插入null?

如果我們查看 ConcurrentHashMap 的源碼,就能發(fā)現(xiàn)為什么 ConcurrentHashMap 不能插入 null 了,以下是 ConcurrentHashMap 添加元素時的部分核心源碼:qOv28資訊網(wǎng)——每日最新資訊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 添加元素的第一行源碼就可以看出,當(dāng) key 或 value 為 null 時,會直接拋出空指針異常,這就是 ConcurrentHashMap 之所以不能插入 null 的根本原因了,因為源碼就是這樣設(shè)計的。qOv28資訊網(wǎng)——每日最新資訊28at.com

3.更深層次的原因

那么問題來了,為什么 ConcurrentHashMap 的實現(xiàn)源碼中,不允許為 key 或者是 value 設(shè)置 null 呢?qOv28資訊網(wǎng)——每日最新資訊28at.com

這就要從 ConcurrentHashMap 的使用場景說起了,在 Java 中,ConcurrentHashMap 是用于并發(fā)環(huán)境中執(zhí)行的線程安全的容器,而 HashMap 是用于單線程環(huán)境下執(zhí)行的非線程安全的容器,而并發(fā)環(huán)境下的運行更復(fù)雜,如果我們允許 ConcurrentHashMap 的 key 或者是 value 為 null 的情況下,就會存在經(jīng)典的“二義性問題”。qOv28資訊網(wǎng)——每日最新資訊28at.com

(1)什么是二義性問題?

所謂的二義性問題指的是代碼或表達式存在多種理解或解釋,導(dǎo)致程序的含義不明確或模糊。qOv28資訊網(wǎng)——每日最新資訊28at.com

以 ConcurrentHashMap 不允許為 null 的二義性問題來說,null 其實有以下兩層含義:qOv28資訊網(wǎng)——每日最新資訊28at.com

  • 這個值本身設(shè)置的是 null,null 在這里表示的是一種具體的“null”值狀態(tài)。
  • null 還表示“沒有”的意思,因為沒有設(shè)置,所以啥也沒有。

所以,如果 ConcurrentHashMap 允許插入 null 值,那么就會存在二義性問題。qOv28資訊網(wǎng)——每日最新資訊28at.com

那就有同學(xué)會問了,為什么 HashMap 允許插入 null,它就不怕有二義性問題嗎?qOv28資訊網(wǎng)——每日最新資訊28at.com

(2)可證偽的HashMap

HashMap 之所以不怕二義性問題的原因是,HashMap 的設(shè)計是給單線程使用的,而單線程下的二義性問題是能被證明真?zhèn)蔚模砸簿筒淮嬖诙x性問題了(能被證明的問題就不是二義性問題)qOv28資訊網(wǎng)——每日最新資訊28at.com

例如,當(dāng)我們給 HashMap 的 key 設(shè)置為 null 時,我們可以通過 hashMap.containsKey(key) 的方法來區(qū)分這個 null 值到底是存入的 null?還是壓根不存在的 null?這樣二義性問題就得到了解決,所以 HashMap 的二義性問題可被證明真?zhèn)危跃筒慌露x性問題,因此也就可以給 key 或者 value 設(shè)置 null 了。qOv28資訊網(wǎng)——每日最新資訊28at.com

(3)不可證偽的ConcurrentHashMap

而 ConcurrentHashMap 就不一樣了,因為 ConcurrentHashMap 是設(shè)計在多線程下使用的,而多線程下的二義性問題是不能被證明真?zhèn)蔚模远x性問題是真實存在的。qOv28資訊網(wǎng)——每日最新資訊28at.com

因為在你在證明二義性問題的同時,可能會有另一個線程影響你的執(zhí)行結(jié)果,所以它的二義性問題就一直存在。qOv28資訊網(wǎng)——每日最新資訊28at.com

例如,當(dāng) ConcurrentHashMap 未設(shè)置 key 為 null 時,會有這樣一個場景,當(dāng)一個線程 A 調(diào)用了 concurrentHashMap.containsKey(key),我們期望返回的結(jié)果是 false,但在我們調(diào)用 concurrentHashMap.containsKey(key) 之后,未返回結(jié)果之前,線程 B 又調(diào)用了 concurrentHashMap.put(key,null) 存入了 null 值,那么線程 A 最終返回的結(jié)果就是 true 了,這個結(jié)果和我們之前預(yù)想的 false 完全不一樣,這就是不能被證偽的二義性問題。qOv28資訊網(wǎng)——每日最新資訊28at.com

所以說,多線程的執(zhí)行比較復(fù)雜,在多線程下 null 的二義性問題是不能被證明真?zhèn)蔚模ㄒ驗樵谝粋€線程執(zhí)行驗證時,可能會有另一個線程改動結(jié)果,造成結(jié)果不準(zhǔn)確),所以 ConcurrentHashMap 為了避免這個二義性問題,所以就在源碼中禁用了 null 值作為 key 或 value。qOv28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-92476-0.html高德面試:為什么Map不能插入Null?

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 轉(zhuǎn)轉(zhuǎn)回收業(yè)務(wù)策略中心的實踐

下一篇: 通過Spring Boot結(jié)合實時流媒體技術(shù)對考試過程進行實時監(jiān)控

標(biāo)簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 石渠县| 卓尼县| 历史| 南充市| 石景山区| 湘潭市| 新平| 宜兰市| 安塞县| 南岸区| 当阳市| 阿拉善右旗| 北宁市| 开平市| 长子县| 南丹县| 吉木萨尔县| 怀仁县| 嘉义县| 图片| 陵川县| 邯郸市| 通州市| 潼南县| 广元市| 砀山县| 信丰县| 宝山区| 洪泽县| 海原县| 卓尼县| 遵义县| 庆云县| 京山县| 岳阳县| 桓台县| 卓尼县| 旌德县| 祁阳县| 达日县| 遂宁市|