Java高頻面試之集合-17

hello啊,各位觀眾姥爺們!!!本baby今天來報道了!哈哈哈哈哈嗝🐶

面試官:JDK 8 對 HashMap 主要做了哪些優化呢?為什么要這么做?


JDK 8 對 HashMap 的主要優化及原因

JDK 8 對 HashMap 的實現進行了多項關鍵優化,顯著提升了其在高沖突場景下的性能內存效率。以下是主要優化點及其設計動機:


一、鏈表轉紅黑樹(Treeify)

優化內容
當單個桶(Bucket)中的鏈表長度超過閾值(默認 8)且哈希表容量 ≥ 64 時,鏈表會被轉換為紅黑樹;當樹節點數 ≤ 6 時,紅黑樹退化為鏈表。

原因

  • 解決鏈表過長導致的性能問題
    鏈表查詢的時間復雜度為 O(n),而紅黑樹的查詢復雜度為 O(log n)。在高沖突場景下,樹化能顯著減少查找時間。
  • 平衡內存與性能
    紅黑樹節點(TreeNode)的內存開銷高于鏈表節點(Node),因此設置退化的閾值(6)以避免小規模數據下的內存浪費。

源碼示例

// 鏈表轉紅黑樹的條件(容量 ≥ 64 且鏈表長度 ≥ 8)
if (binCount >= TREEIFY_THRESHOLD - 1) {treeifyBin(tab, hash);break;
}

二、哈希函數優化

優化內容
JDK 8 改進了哈希值計算方式,通過 高位異或(XOR) 增強散列性:

static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

原因

  • 減少哈希沖突
    將哈希碼的高 16 位與低 16 位異或,使得更多位數參與索引計算((n - 1) & hash),避免僅依賴低位導致的沖突。
  • 提升分布均勻性
    例如,若容量為 16(二進制 10000),原哈希碼低位重復性高,異或高位后分布更均勻。

三、擴容機制優化

優化內容
擴容時,通過 高位掩碼判斷 元素的新位置,避免重新計算哈希值:

if ((e.hash & oldCap) == 0) {// 新索引 = 原索引
} else {// 新索引 = 原索引 + 原容量
}

原因

  • 減少計算開銷
    原擴容需重新計算所有元素的哈希值和索引,JDK 8 直接通過哈希值的特定位判斷位置,性能提升顯著。
  • 元素均勻拆分
    擴容后,原桶中的元素被均分到兩個新桶中(低位桶和高位桶),減少鏈表或樹的深度。

四、樹化條件優化

優化內容
鏈表轉紅黑樹需滿足 容量 ≥ 64,否則優先擴容而非樹化。

原因

  • 避免小容量下過早樹化
    若容量較小(如 16),擴容可有效減少沖突概率,此時樹化反而增加內存開銷且收益有限。
  • 優先利用擴容分散沖突
    擴容后哈希分布更均勻,可能自然解決沖突,減少樹化需求。

五、性能對比與設計權衡
場景JDK 7 鏈表查詢JDK 8 紅黑樹查詢優化收益
鏈表長度 = 8O(8) → 8次遍歷O(log 8) → 3次比較性能提升 60%+
鏈表長度 = 64O(64) → 64次遍歷O(log 64) → 6次比較性能提升 90%+

六、總結與適用場景
優化點解決的問題適用場景
鏈表轉紅黑樹高沖突下鏈表查詢效率低頻繁插入、高哈希沖突的鍵值對場景
哈希函數優化哈希分布不均導致沖突概率高鍵的 hashCode() 實現質量參差不齊
擴容機制優化擴容時重新哈希的性能瓶頸大規模數據動態擴容場景

在這里插入圖片描述

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

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

相關文章

計算機二級:函數基礎題

函數基礎題 第一題 rinput("請輸入半徑:") c3.1415926*r*2 print("{:.0f}".format(c))輸出: Type Error第二題 a7 b2 print(a%2)輸出 1第三題 ab4 def my_ab(ab,xy):abpow(ab,xy)print(ab,end"\n") my_ab(ab,2)prin…

C# 屬性(Property)?詳解

在 C# 中,?屬性(Property)? 是類或結構體中的成員,用于封裝對私有字段(稱為 ?backing field?)的訪問,提供更靈活和安全的數據操作方式。屬性通過 get 和 set 訪問器控制對數據的讀寫&#x…

iPhone 16如何翻譯文檔?文檔翻譯技巧、軟件推薦

在全球化的今天,跨語言交流變得越來越頻繁,而文檔翻譯更是成為許多人日常工作和學習中的重要需求。作為蘋果公司最新推出的旗艦機型,iPhone 16憑借其強大的硬件性能和豐富的軟件生態,為我們提供了多種便捷的文檔翻譯方式&#xff…

HRP方法全文總結與模型流程解析

背景與問題 傳統二次優化方法(如Markowitz的CLA)存在三大問題: 不穩定性:協方差矩陣的高條件數導致逆矩陣計算誤差放大,權重劇烈波動。 集中性:優化結果過度集中于少數資產,易受個體風險沖擊。…

解決項目一直在構建中的問題:以 IntelliJ IDEA 為例提高共享堆內存

在使用 IntelliJ IDEA 時,開發者可能會遇到項目長期處于構建狀態的問題。這種情況將嚴重影響開發效率。通常,這種問題的一個常見原因是構建進程所分配的堆內存不足。本文將以 IntelliJ IDEA 為背景,介紹如何通過提高共享堆內存來解決此問題&a…

金橙子刪除打標對象

注意在使用金橙子根據對象名稱刪除對象時要注意,每刪除一個對象,所有對象的索引都將改變。 如果你是用for去遍歷,再根據索引獲取打標對象名稱的話就會出現漏的掉的問題。 改進方法 1,將要刪除的對象找到后,統一存放在一個集合中。再根據這個要刪除的對象集合再一個個去遍…

JVM常見概念之條件移動

問題 當我們有分支頻率數據時,有什么有趣的技巧可以做嗎?什么是條件移動? 基礎知識 如果您需要在來自一個分支的兩個結果之間進行選擇,那么您可以在 ISA 級別做兩件不同的事情。 首先,你可以創建一個分支&#xff…

MANISKILL3:GPU 并行機器人模擬和渲染,用于通用的具身AI

本文介紹了一種名為ManiSkill3的機器人仿真系統,它采用了GPU并行化技術,并針對通用性進行了優化。該系統支持多種視覺輸入方式和異構模擬,能夠在物理場景中進行高效的仿真和渲染,達到比其他平臺更快的速度和更少的GPU內存使用量。…

計算機網絡高頻(三)UDP基礎

計算機網絡高頻(三)UDP基礎 1.UDP的頭部格式是什么樣的?? UDP 頭部具有以下字段: 源端口(Source Port):16 位字段,表示發送方的端口號。目標端口(Destination Port):16 位字段,表示接收方的端口號。長度(Length):16 位字段,表示 UDP 數據報(包括頭部和數據部…

微信小程序中使用Less樣式方法

在微信小程序中使用Less樣式,可以通過以下步驟實現。主要原理是借助Visual Studio Code(VSCode)的插件將Less文件自動編譯為小程序支持的.wxss文件,或通過微信開發者工具的擴展功能直接集成Less編譯環境。以下是具體方法&#xff…

Leetcode 刷題筆記 圖論part05

卡碼網 107 尋找存在的路徑 初識并查集 并查集功能: 尋找根節點,函數: find(int u),也就是判斷這個節點的祖先節點是哪個將兩個節點接入到同一個集合,函數: join(int u, int v),將兩個節點連在同一個根節點上判斷兩…

SpringBoot星之語明星周邊產品銷售網站設計與實現

在當今數字化時代,明星周邊產品的線上銷售已成為一種趨勢。幽絡源作為一站式綜合平臺,不僅提供免費源碼、網絡兼職資源,還分享各類技術教程。本文將詳細介紹基于SpringBoot的星之語明星周邊產品銷售網站的設計與實現,幫助開發者快…

怎樣對比找到兩個git倉庫的差異

怎樣對比找到兩個git倉庫的差異 陳拓 2024/12/24-2024/12/28 1. 概述 要比較兩個Git倉庫的差異,可以使用git diff命令。你需要先將兩個倉庫的克隆版本都檢出到本地,然后在對應的目錄中運行git diff命令。 下面我們以YDLIDAR ROS2驅動程序ydlidar_ros2…

C語言-裝飾器模式詳解與實踐 - LED控制系統

文章目錄 C語言裝飾器模式詳解與實踐 - LED控制系統1. 什么是裝飾器模式?2. 為什么需要裝飾器模式?3. 實際應用場景4. 代碼實現4.1 頭文件 (led_decorator.h)4.2 實現文件 (led_decorator.c)4.3 使用示例 (main.c) 5. 代碼分析5.1 關鍵設計點5.2 實現特點…

Go常見問題與回答(下)

文章目錄 1、通過指針變量 p 訪問其成員變量 name,有哪幾種方式?2、代碼,說出結果3、擴容提,代碼,說出結果4、指出下面這段代碼的錯誤之處5、是否通過編譯6、關于字符串連接,下面語法正確的是7、關于iota&a…

JVM 核心知識點總結

🧑 博主簡介:CSDN博客專家,歷代文學網(PC端可以訪問:https://literature.sinhy.com/#/literature?__c1000,移動端可微信小程序搜索“歷代文學”)總架構師,15年工作經驗,…

SQL中體會多對多

我們可以根據學生與課程多對多關系的數據庫模型,給出實際的表數據以及對應的查詢結果示例,會用到JOINLEFT JOIN兩種連接 1. 學生表(students) student_idstudent_name1張三2李四3王五 2. 課程表(courses&#xff09…

ES如果要查10條數據需要從各個分片上各取多少條數據?

目錄 ES如果要查10條數據需要從各個分片上各取多少條數據? 簡單查詢(如 match_all 或 term 查詢) 深度分頁查詢(如 from + size 查詢) 聚合查詢 什么叫聚合查詢? 聚合查詢的基本結構 常見的聚合類型 聚合查詢的執行過程 聚合查詢的示例 聚合查詢的應用場景 注意…

人機交互自學引導

第1關:輸出“Hello World!” # 在下面一行補充代碼,輸出“Hello World!” print(Hello World!) 第2關:輸出“李白,你好!” # 在下面補充代碼,在兩行中依次輸出“李白,你好!”和“…

CentOS 7 更換 yum 源(阿里云)+ 擴展 epel 源

CentOS 7 更換 yum 源(阿里云) 擴展 epel 源 一、備份現有 yum 源二、下載 yum 源(任選其一即可)三、清理并生成緩存四、安裝 EPEL 擴展源(根據需要下載)五、驗證是否生效六、一鍵腳本(阿里云源…