Hashmap源碼

目錄

HashMap底層原理

JDK1.8及以后底層結構為:數組+鏈表+紅黑樹

默認參數

擴容機制

數組

鏈表

紅黑樹

HashMap為什么用紅黑樹不用B樹

HashMap什么時候擴容

HashMap的長度為什么是 2的 N 次方


HashMap底層原理

JDK1.8及以后底層結構為:數組+鏈表+紅黑樹

HashMap是Java集合框架中一種基于哈希表實現的Map接口,它存儲鍵值對,鍵是唯一的,而值可以重復。它的底層結構是一個數組結構,在實際情況中,這個數組被分為多個“桶(bucket)”,每個桶內存儲的是鏈表或紅黑樹(JDK1.8中引入),具體使用哪種取決于鏈表的長度和當前Map的大小

  • 默認參數

    • 默認負載因子(load factor):0.75。負載因子是衡量HashMap滿的程度的一個標準。當HashMap中的元素數量達到容量與負載因子的乘積時,就會進行擴容。

    • 默認容量(capacity):16,必須是2的冪。

  • 擴容機制

    • 當HashMap中的元素數量達到threshold時,即當前容量乘以負載因子,HashMap會進行擴容操作。

    • 擴容操作會創建一個新的數組,其大小為原數組大小的兩倍,并重新計算每個鍵的哈希值和在新數組中的位置。

    • 這個過程涉及到重新計算每個鍵的哈希值,并將所有的鍵值對重新插入到新的數組中,因此擴容是一個比較耗費性能的操作。

  • 數組

    • 作用:數組是HashMap存儲元素的主要結構,每個數組元素是一個桶(bucket),可以存儲一個或多個鍵值對(Entry)。

    • 默認大小:默認初始容量為16(必須是2的冪)。

    • 擴容機制:當HashMap中的元素數量達到容量與負載因子乘積時,即size >= threshold(threshold = capacity * load factor),數組會進行擴容操作,擴容為原來的兩倍大小。

對于默認的容量和負載因子,threshold 的默認值是:
threshold = 16 * 0.75 = 12
這意味著當 HashMap 中的元素數量達到 12 時,HashMap 會進行擴容操作。擴容后的新容量是原容量的兩倍為36,同時 threshold 也會相應地更新為新的容量乘以負載因子。
  • 鏈表

    • 作用:當數組的同一個桶位置(即索引相同)發生哈希碰撞時,多個鍵值對會以鏈表的形式存儲。JDK 1.8之前,HashMap就是使用鏈表處理沖突;JDK 1.8之后,當鏈表長度大于一定閾值時,鏈表會轉換為紅黑樹。

    • 默認閾值:鏈表轉紅黑樹的閾值為8(當鏈表長度大于8時,會轉換為紅黑樹)。

  • 紅黑樹

    • 作用:為了提高HashMap的性能,當鏈表長度過長時,鏈表會被轉換成紅黑樹。這樣可以減少搜索時間,從O(n)降低到O(log n)。

    • 默認閾值:鏈表轉回鏈表的閾值為6(當紅黑樹中的節點數量小于6時,會轉換回鏈表)。

HashMap為什么用紅黑樹不用B樹

HashMap 使用紅黑樹(Red-Black Tree)而不是 B 樹的主要原因是效率和復雜度。

  • 效率:紅黑樹相對于 B 樹,在插入、刪除和查找操作上具有更好的平均性能。紅黑樹的平衡性質可以保證樹的高度相對較小,從而減少了搜索的路徑長度,提高了操作的效率。

  • 復雜度:B 樹是一種多路搜索樹,節點可以包含多個關鍵字和指針,適合用于磁盤存儲等場景,可優化磁盤 IO 操作。然而,在內存中的數據結構中,紅黑樹的實現更為簡單,代碼的復雜度較低。同時,紅黑樹的性能在典型的 HashMap 使用場景中通常表現出良好的性能。

另外,HashMap 維護了一個哈希表和一個鏈表或紅黑樹的混合結構(JDK8 之后),當發生哈希沖突時,會使用鏈表或紅黑樹來處理沖突。鏈表適合處理沖突較少的情況,而紅黑樹則適合處理沖突較多的情況。紅黑樹相對于鏈表具有更高的查找效率,因此在沖突較多的情況下能夠提供更好的性能。

總之,HashMap 使用紅黑樹而不是 B 樹主要是出于對效率和復雜度的考慮。紅黑樹在內存中的實現更簡單,對于典型的 HashMap 使用場景能夠提供良好的性能,且適用于處理沖突較多的情況。


最簡回答:HashMap使用紅黑樹而不是B樹,是因為紅黑樹相對于B樹在插入、刪除和查找等操作上的平衡性能更好,且紅黑樹的節點比B樹的節點更小,占用的內存更少,適合存儲在內存中的數據結構。

HashMap什么時候擴容

  • 在JDK1.7中,當HashMap中元素數量超過當前容量與負載因子(默認為0.75)的乘積時,會觸發擴容操作,擴容后的容量為當前容量的兩倍。例如,初始容量為16,當元素數量達到12時會觸發擴容,擴容后的容量為32。

  • 在JDK 1.8中,HashMap的擴容和紅黑樹轉換是兩個獨立的操作,且順序是先擴容,然后再進行紅黑樹的轉換。當HashMap中的元素數量超過負載因子(默認為0.75)與數組容量的乘積時,會觸發擴容操作。擴容會重新調整數組的大小,并將原來數組中的元素重新分配到新的數組位置上。擴容操作會導致原本哈希沖突較多的鏈表長度變長,因此當鏈表長度超過閾值(默認為8)時,會將鏈表轉化為紅黑樹。綜上所述,在JDK 1.8中,HashMap的操作順序是先擴容,然后再進行紅黑樹的轉換。擴容是為了減少哈希沖突,提高HashMap的性能和效率,而鏈表轉紅黑樹的操作則是為了在特定情況下提供更好的查找、插入和刪除元素的性能。

HashMap的長度為什么是 2的 N 次方

為了能讓 HashMap 存數據和取數據的效率高,盡可能地減少 hash 值的碰撞,也就是說盡量把數

據能均勻的分配,每個鏈表或者紅黑樹長度盡量相等。我們首先可能會想到 % 取模的操作來實現。

下面是回答的重點喲:

取余(%)操作中如果除數是 2 的冪次,則等價于與其除數減一的與(&)操作(也就是說hash % length == hash &(length - 1) 的前提是 length 是 2 的 n 次方)。并且,采用二進制位操作 & ,相對于 % 能夠提高運算效率。

這就是為什么 HashMap 的長度需要 2 的 N 次方了


最簡回答:HashMap的長度選擇為2的N次方是為了提高散列算法的效率和分布均勻性,通過使用2的冪次方作為長度,可以確保哈希碼的高位和低位可以均勻參與到散列計算中,減少哈希沖突的發生,并提高散列算法的效率和性能。

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

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

相關文章

【JAVA 字符串常量池、new String的存儲機制、==與equals的區別,以及字符串重新賦值時的指向變化】

系列文章目錄 提示:這里可以添加系列文章的所有文章的目錄,目錄需要自己手動添加 提示:寫完文章后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄系列文章目錄代碼原理解錯誤邏輯理解理解與修正&#xff1a…

博客項目 Spring + Redis + Mysql

基礎模塊1. 郵箱發送功能最初設計的接口 (雛形)public interface EmailService {/*** 發送驗證碼郵件** param email 目標郵箱* return 發送的code* throws RuntimeException 如果發送郵件失敗,將拋出異常*/String sendVerificationCode(Stri…

前端處理導出PDF。Vue導出pdf

前言:該篇主要是解決一些簡單的頁面內容導出為PDF1.安裝依賴使用到兩個依賴,項目目錄下運行這兩個//頁面轉換成圖片 npm install --save html2canvas //圖片轉換成pdf npm install jspdf --save 2.創建通用工具類exportPdf.js文件可以保存在工具類目錄下…

【GM3568JHF】FPGA+ARM異構開發板燒錄指南

1. Windows燒錄說明 SDK 提供 Windows 燒寫工具(工具版本需要 V3.31或以上),工具位于工程根目錄: tools/ ├── windows/RKDevTool 如下圖,編譯生成相應的固件后,設備燒寫需要進入 MASKROM 或 LOADER 燒寫模式,準備…

C++ 多進程編程深度解析【C++進階每日一學】

文章目錄一、引言二、核心概念:進程 (Process)功能與作用三、C 多進程的實現方式四、核心函數詳解1. fork() - 創建子進程函數原型功能說明返回值完整使用格式2. wait() 和 waitpid() - 等待子進程結束函數原型參數與返回值詳解3. exec 系列函數 - 執行新程序函數族…

一周學會Matplotlib3 Python 數據可視化-繪制面積圖(Area)

鋒哥原創的Matplotlib3 Python數據可視化視頻教程: 2026版 Matplotlib3 Python 數據可視化 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 課程介紹 本課程講解利用python進行數據可視化 科研繪圖-Matplotlib,學習Matplotlib圖形參數基本設置&…

北京JAVA基礎面試30天打卡11

1.索引創建注意事項 適合的場景 1.頻繁使用where語句查詢的字段 2.關聯字段需要建立索 3.如果不創建索引,那么在連接的過程中,每個值都會進行一次全表掃描 4.分組和排序字段可以建立索引因為索引天生就是有序的,在分組和排序時優勢不言而喻 5…

vscode無法檢測到typescript環境解決辦法

有一個vitereacttypescript項目,在工作電腦上一切正常。但是,在我家里的電腦運行,始終無法檢測到typescript環境。即使出現錯誤的ts語法,也不會有報錯提示,效果如下:我故意將一個string類型,傳入…

【MCP開發】Nodejs+Typescript+pnpm+Studio搭建Mcp服務

MCP服務支持兩種協議,Studio和SSE/HTTP,目前官方提供的SDK有各種語言。 開發方式有以下幾種: 編程語言MCP命令協議發布方式PythonuvxSTUDIOpypiPython遠程調用SSE服務器部署NodejspnpmSTUDIOpnpmNodejs遠程調用SSE服務器部署… 一、初始化項…

vscode使用keil5出現變量跳轉不了和搜索全局不了

vscode使用keil5出現變量跳轉不了,或者未包含文件,或者未全局檢索; 參考如下文章后還會出現; 為什么vscode搜索欄只搜索已經打開的文件_vscode全局搜索只能搜當前文件-CSDN博客 在機緣巧合之下發現如下解決方式: 下載…

命名空間——網絡(net)

命名空間——網絡(net) 一、網絡命名空間:每個都是獨立的“網絡房間” 想象你的電腦是一棟大樓,每個網絡命名空間就是大樓里的一個“獨立房間”: 每個房間里有自己的“網線接口”(網卡)、“門牌…

一文讀懂16英寸筆記本的實際尺寸與最佳應用場景

當您搜索"16寸筆記本電腦長寬"時,內心真正在問的是什么?是背包能否容納?桌面空間是否足夠?還是期待屏幕尺寸與便攜性的完美平衡?這個看似簡單的尺寸數字背后,凝結著計算機制造商對用戶體驗的深刻…

Android Studio中創建Git分支

做一些Android項目時,有時候想要做一些實驗性的修改,這個實驗可能需要很多步驟,所以不是一時半會能完成的,這就需要在實驗的過程中不斷修改代碼,且要提交代碼,方便回滾或比較差異,但是既然是實驗…

內存可見性和偽共享問題

文章目錄什么是內存可見性問題為什么會出現可見性問題解決可見性問題的方法1. 使用volatile關鍵字2. 使用synchronized3. 使用java.util.concurrent包下的原子類什么是偽共享問題CPU緩存行偽共享的危害解決偽共享的方法1. 緩存行填充2. 使用Contended注解(JDK 8&…

Spring MVC 九大組件源碼深度剖析(三):ThemeResolver - 動態換膚的奧秘

文章目錄一、主題機制的核心價值二、核心接口設計三、四大實現類源碼解析1. FixedThemeResolver(固定主題策略)2. CookieThemeResolver(Cookie存儲策略)3. SessionThemeResolver(Session存儲策略)4. Abstra…

一、Docker本地安裝

((這里引用知乎上大佬的說法:https://www.zhihu.com/question/48174633 服務器虛擬化解決的核心問題是資源調配,而容器解決的核心問題是應用開發、測試和部署。 一、參考帖子 Ubuntu 的 |Docker 文檔 【docker】ubuntu完全卸載docker及再次安裝_ubuntu…

LeetCode 分類刷題:2962. 統計最大元素出現至少 K 次的子數組

題目給你一個整數數組 nums 和一個 正整數 k 。請你統計有多少滿足 「 nums 中的 最大 元素」至少出現 k 次的子數組,并返回滿足這一條件的子數組的數目。子數組是數組中的一個連續元素序列。示例 1:輸入:nums [1,3,2,3,3], k 2 輸出&#…

10分鐘掌握swift

整理一個 10分鐘掌握 Swift 的精華指南,用一個 Demo 串聯 Swift 的核心語法、數據結構、函數、類/結構體和閉包,讓你快速入門。1?? 基礎語法與變量import Foundation // 引入基礎庫// 變量和常量 var name: String "Alice" // 可變 let…

【完整源碼+數據集+部署教程】食品分類與實例分割系統源碼和數據集:改進yolo11-AggregatedAttention

背景意義 研究背景與意義 隨著全球食品產業的快速發展,食品安全和質量控制日益成為社會關注的焦點。食品分類與實例分割技術的應用,能夠有效提升食品識別的準確性和效率,為食品監管、營養分析以及智能餐飲等領域提供重要支持。傳統的食品識別…

C# 中的N+1問題

目錄 含義 影響 避免方法 1. 立即加載(Eager Loading) 2. 顯式加載(Explicit Loading) 3. 投影(Projection) 4. 批處理查詢 5. 禁用延遲加載 含義 N1 問題 是 ORM(對象關系映射&#x…