HashMap底層相關內容

HashMap的底層結構:
1.7之前 數組加鏈表,當兩個值進行插入的時候 采用頭插法進行插入,可能會造成死循環
1.8之后 數組加鏈表/紅黑樹,當兩個值進行插入的時候,采用尾插法進行插入,不會造成死循環

HashMap底層put源碼:

  • 1.7之前 會先進行判斷當前插入的值的key是否為null,如果是null
    檢查數組為0的索引下標位置是否為空,如果不是空,就會把原來的值取出來放入oldValue返回回去,并采用頭插法將新put的值放到原來的位置上,舊的值放到新值下面。
    如果是空,就會直接把put的值放入索引下標的位置上。
    如果key不為null會根據key調用方法indexFor計算出當前key所要存儲的數組的索引下標的值,在判斷當前下標下是否有元素,重復上面的操作,
    如果有的話還要進行判斷當前的key是否存在,如果存在就直接覆蓋并返回之前的值。
    之后將modCount加一,為了判斷集合在迭代的時候,值是否發生了修改
    之后就會添加一個新的鏈表節點,添加之前先判斷當前的數組用了多少,
    如果當前已用的數組位置達到了數組長度的0.75并且即將添加位置不為空就會發生擴容機制,沒有達到會頭插法添加元素,size++
  • 1.8之后 會先進行hash運算取出hash值,再判斷當前hashMap的數組是否為空,如果為空初始化數組
    判斷當前數組索引位置的值是否為空,如果為空,新建加入一個節點
    如果不為空,判斷當前索引下標位置的元素是否與新put的值的key相同,如果相同,將值取出來放到e中
    如果不相同,判斷當前索引下標位置的節點是否是樹節點,如果是,去調用樹方法去判斷 加入節點等
    如果不是樹節點,表示是鏈表節點,進行循環遍歷,將p.next給e,如果e是空的話,直接將put進來的值插入到p.next位置,并判斷是否已經達到了樹化閾值
    達到了樹化閾值了判斷數組長度是否達到了64,數組長度也達到了進行樹化,跳出循環
    如果e不為空,判斷e的hash值是否和put進來的值的key的hash一樣,如果相同,直接跳出循環
    將e的值放到一個oldValue中進行返回
    修改modCount的值進行++,size進行++,判斷size的值是否達到了擴容情況,進行擴容。

HashMap在1.8的時候為什么要轉換為紅黑樹?
因為在1.7的時候如果出現hash沖突就會將沖突的數據加入到鏈表中,如果沖突的數據多了,鏈表的數據就會太長,這樣的話就會造成查詢效率下降
紅黑樹的查詢效率大于鏈表。紅黑樹的加入是為了解決hash沖突,提高查詢效率。

樹化閾值為什么是8?
這涉及到一個泊松分布,有人調查過,如果閾值達到8的時候,造成hash沖突的概率是千萬分之一級別,沖突的概率就已經很小了

反樹化閾值為什么是6?
因為如果反樹化閾值是8,這樣不太穩定,如果數組的同一節點在加上一個數就會導致進行樹化,而如果減少一個數就會進行鏈表化,這樣來回樹化和反樹化,會導致性能降低
而如果反樹化閾值太小,很少的數就會導致轉換成紅黑樹,完全沒必要

加載因子為什么是0.75?
這是對時間和空間之間取得一個折中值,如果太大了是1的話,會導致hash沖突增加,降低性能,浪費時間
如果太小,是0.5的話,會導致還有一半的空間沒有用就進行擴容,浪費空間

hashmap默認初始化大小是多少?為什么按照2的冪次方進行擴容?
初始化大小是16,因為2的冪次方-1是多個1的組合,就像1111,當獲取添加元素到數組的哪一個索引下標的時候用hash碼的值和2的冪次方-1進行取余運算,因為是取余運算
在相同的位置上,hash碼值是什么,結果就是什么,降低了得到同一索引下標的可能性,也就降低了hash沖突。

hashmap擴容的條件?
當數組中插入元素的長度達到數組的長度*加載因子的時候會進行擴容
當同一個索引下標位置鏈表的長度達到8并且數組的長度還沒有達到64的時候

hashmap是怎么進行擴容的?1.7
hashMap的初始化容量如果不是2的冪次方,實際初始化容量會是接近自定義初始化容量的最小的2的冪次方
按照原數組長度的2倍進行擴容,會將原來的數組的索引下標位置的部分元素轉移的原數組索引下標位置加上原數組的長度的位置上
先進行循環遍歷要進行轉移的數組的索引下標,里面在進行循環遍歷要轉移的數據
將e指向要進行轉移的元素,將next指向e的下一個元素,在將e.next指向要轉移的新數組的對應下標位置,再將e賦值給新數組的對應索引下標,相當于是往下移了一位,
再將next的值賦給e,再次執行同樣的操作。

為什么hashMap在1.7的時候采用頭插法,在1.8變成了尾插法?
因為在高并發情況下,在擴容進行數據轉移的時候,使用頭插法可能導致next指向已經轉移到新數組的數據,再次使用e.next指向新數組索引下標的時候,
的是鏈表上面的元素,導致成為一個環,造成了死循環。
而使用尾插法不會導致這樣的情況。

hashMap里面的key和value可以是空值嗎?
key和value都可以是空值,但是key只能有一個是空值

HashMap是線程安全的嗎?
不是線程安全的,但是可以通過使用Collections的synchronizedMap()變得線程安全,也可以使用copyOnWrite變得線程安全

HashMap和HashTable的區別是什么?
HashMap是線程不安全的,HashTable是線程安全的
HashMap允許Key和Value為空,HashTable不允許鍵或值為空,如果鍵為空會報空指針異常
HashMap遍歷的順序不確定,HashTable的遍歷順序是按照插入的順序進行遍歷的
HashMap的性能相對較高一點,HashTable的性能相對較低

HashMap和LinkedHashMap的區別?
HashMap是無序的,獲取的順序和插入順序不一致,LinkedHashMap是有序地,獲取元素的順序和插入順序是一致的
HashMap底層就是數組加鏈表/紅黑樹,LinkedHashMap的底層是在HashMap的基礎上維護了一個雙向鏈表

HashMap和ConcurrentHashMap的區別是什么?
HashMap是線程不安全的,ConcurrentHashMap是線程安全的
HashMap由于線程不安全,所以并發情況下可能導致數據不一致或拋出異常,ConcurretHashMap使用了分段鎖,所以不同的段可以被不同的線程訪問,提高了并發性
HashMap沒有鎖,要保證線程安全需要再外部加上同步機制,ConcurrentHashMap使用了分段式鎖, 鎖得到粒度小
HashMap:在擴容時需要重新計算哈希值,重新分配元素位置,可能會導致鏈表長度過長,影響性能。ConcurrentHashMap:在擴容時只需要對某個段進行擴容,不會影響其他段,減少了擴容帶來的性能損耗。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39280.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39280.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39280.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

xml轉map工具類

背景&#xff1a;最近遇到接口返回是xml&#xff0c;所以需要整一個轉換的工具類&#xff0c;方便后續其他xml處理。 依賴引入&#xff1a; <dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.1</versi…

澎峰科技|邀您關注2023 RISC-V中國峰會!

峰會概覽 2023 RISC-V中國峰會&#xff08;RISC-V Summit China 2023&#xff09;將于8月23日至25日在北京香格里拉飯店舉行。本屆峰會將以“RISC-V生態共建”為主題&#xff0c;結合當下全球新形勢&#xff0c;把握全球新時機&#xff0c;呈現RISC-V全球新觀點、新趨勢。 本…

linux下nginx配置https和反向代理本地端口

1 修改配置文件/etc/nginx/sites-enabled/default 在配置文件中增加一個server用來做https端口監聽&#xff0c; ssl_certificate和ssl_certificate_key修改為自己申請的https認證文件 server{listen 443 ssl;server_name www.dogrich.net;#root /var/www/html;# 上面配置的…

《3D 數學基礎》12 幾何圖元

目錄 1 表達圖元的方法 1.1 隱式表示法 1.2 參數表示 1.3 直接表示 2. 直線和射線 2.1 射線的不同表示法 2.1.1 兩點表示 2.1.2 參數表示 2.1.3 相互轉換 2.2 直線的不同表示法 2.2.1 隱式表示法 2.2.2 斜截式 2.2.3 相互轉換 3. 球 3.1 隱式表示 1 表達圖元的方…

C語言的使用技巧--在IO操作中的移位和快速配置

在WB32F103&#xff08;ARM cortex m3內核&#xff0c;96Mhz&#xff09;的gpio初始化中有一段代碼&#xff0c;充分的結合了硬件特征并使用C語言的技巧來快速的配置對應的GPIO的功能&#xff0c;堪稱經典和楷模&#xff0c;代碼異常簡潔&#xff0c;執行速度快&#xff0c;配置…

【深度學習所有損失函數】在 NumPy、TensorFlow 和 PyTorch 中實現(2/2)

一、說明 在本文中&#xff0c;討論了深度學習中使用的所有常見損失函數&#xff0c;并在NumPy&#xff0c;PyTorch和TensorFlow中實現了它們。 (二-五)見 六、稀疏分類交叉熵損失 稀疏分類交叉熵損失類似于分類交叉熵損失&#xff0c;但在真實標簽作為整數而不是獨熱編碼提…

Python pycparser(c文件解析)模塊使用教程

文章目錄 安裝 pycparser 模塊模塊開發者網址獲取抽象語法樹1. 需要導入的模塊2. 獲取 不關注預處理相關 c語言文件的抽象語法樹ast3. 獲取 預處理后的c語言文件的抽象語法樹ast 語法樹組成1. 數據類型定義 Typedef2. 類型聲明 TypeDecl3. 標識符類型 IdentifierType4. 變量聲明…

語聚AI公測發布,大語言模型時代下新的生產力工具

語聚AI 公測發布 距離語聚AI內測上線已經過去近1個月。 這期間&#xff0c;我們共邀請了近百位資深用戶與行業專家加入語聚AI產品體驗。通過大家的熱情參與積極反饋&#xff0c;我們不斷優化并完善了語聚AI的功能與使用體驗。 經過研發團隊不懈的努力&#xff0c;今天語聚AI終…

【Leetcode】88.合并兩個有序數組

一、題目 1、題目描述 給你兩個按 非遞減順序 排列的整數數組 nums1 和 nums2,另有兩個整數 m 和 n ,分別表示 nums1 和 nums2 中的元素數目。 請你 合并 nums2 到 nums1 中,使合并后的數組同樣按 非遞減順序 排列。 注意:最終,合并后數組不應由函數返回,而是存儲在數…

梅賽德斯-奔馳將成為首家集成ChatGPT的汽車制造商

ChatGPT的受歡迎程度毋庸置疑。OpenAI這個基于人工智能的工具&#xff0c;每天能夠吸引無數用戶使用&#xff0c;已成為當下很受歡迎的技術熱點。因此&#xff0c;有許多公司都在想方設法利用ChatGPT來提高產品吸引力&#xff0c;賣點以及性能。在汽車領域&#xff0c;梅賽德斯…

代碼隨想錄算法訓練營第59天|動態規劃part16|583. 兩個字符串的刪除操作、72. 編輯距離、編輯距離總結篇

代碼隨想錄算法訓練營第59天&#xff5c;動態規劃part16&#xff5c;583. 兩個字符串的刪除操作、72. 編輯距離、編輯距離總結篇 583. 兩個字符串的刪除操作 583. 兩個字符串的刪除操作 思路&#xff1a; 思路見代碼 代碼&#xff1a; python class Solution(object):de…

[國產MCU]-BL602開發實例-I2C與總線設備地址掃描

I2C與總線設備掃描 文章目錄 I2C與總線設備掃描1、I2C介紹2、I2C驅動API介紹3、I2C使用實例I2C (Inter-Intergrated Circuit)是一種串行通訊總線,使用多主從架構,用來連接低速外圍裝置。 每個器件都有一個唯一的地址識別,并且都可以作為一個發送器或接收器。每個連接到總線的…

node-sass是什么

一、Sass&#xff08;Syntactically Awesome Style Sheets&#xff09; 是一種CSS預處理器&#xff0c;它擴展了CSS的功能并提供了更強大的樣式表語言。Sass允許開發人員使用變量、嵌套規則、混合&#xff08;Mixins&#xff09;、繼承等高級功能來編寫更簡潔、可維護的樣式代…

2023年國賽數學建模思路 - 案例:FPTree-頻繁模式樹算法

文章目錄 算法介紹FP樹表示法構建FP樹實現代碼 建模資料 ## 賽題思路 &#xff08;賽題出來以后第一時間在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 算法介紹 FP-Tree算法全稱是FrequentPattern Tree算法&#xff0c;就是頻繁模式樹算法&#xff0c…

QT-Mysql數據庫圖形化接口

QT sql mysqloper.h qsqlrelationaltablemodelview.h /************************************************************************* 接口描述&#xff1a;Mysql數據庫圖形化接口 擬制&#xff1a; 接口版本&#xff1a;V1.0 時間&#xff1a;20230727 說明&#xff1a;支…

基于VUE3+Layui從頭搭建通用后臺管理系統(前端篇)九:自定義組件封裝下

一、本章內容 續上一張,本章實現一些自定義組件的封裝,包括文件上傳組件封裝、級聯選擇組件封裝、富文本組件封裝等。 1. 詳細課程地址: 待發布 2. 源碼下載地址: 待發布 二、界面預覽 三、開發視頻 基于VUE3+Layui從頭搭建通用后臺管

【軟件工程】內聚

概念 是指一個模塊內部個成分之間相互關聯程度的度量。也就是說&#xff0c;凝聚是對模塊內各處理動作組合強度的一種度量。很顯然&#xff0c;一個模塊的內聚越大越好。 偶然凝聚 一個模塊內的各處理元素之間沒有任何聯系&#xff0c;只是偶然地被湊到一起。這種模塊也稱為…

mov轉mp4格式怎么轉?

mov轉mp4格式怎么轉&#xff1f;眾所周知&#xff0c;MOV視頻格式是由蘋果公司推出的常用的視頻格式&#xff0c;能夠在蘋果軟件及設備上使用。但是&#xff0c;如果將其應用于其他軟件和設備上的話&#xff0c;可能會遇到文件無法正常播放的情況。在這個時候&#xff0c;我們需…

Linux MQTT智能家居項目(LED界面的布局設置)

文章目錄 前言一、LED界面布局準備工作二、LED界面布局三、邏輯實現總結 前言 上篇文章我們完成了主界面的布局設置那么這篇文章我們就來完成各個界面的布局設置吧。 一、LED界面布局準備工作 首先添加LED燈光控制的圖標。 將選擇好的LED圖標添加進來&#xff1a; 圖標可以…

drawio導出矢量圖

1.選中要導出的圖 2.導出為pdf 3.用adobe打開pdf&#xff0c;另存為eps