Jdk1.7到Jdk1.8 HashMap 發生了什么變化(底層)

從JDK 1.7到JDK 1.8,HashMap在底層實現上發生了顯著的變化,

主要體現在數據結構、鏈表插入方式、哈希算法、擴容機制以及并發性方面。

以下是具體的變化點:

1. 數據結構的變化

  • JDK 1.7:HashMap的底層數據結構是數組+單向鏈表。當哈希沖突發生時,新的元素會插入到鏈表的頭部(頭插法)。
  • JDK 1.8:HashMap的底層數據結構變為數組+鏈表/紅黑樹。當鏈表長度超過一定閾值(默認為8)時,鏈表會轉換成紅黑樹,以提高查詢效率。這種變化使得HashMap在處理大量數據時能夠保持較好的性能。

2. 鏈表插入方式的變化

  • JDK 1.7:鏈表插入使用的是頭插法,即新的元素會被插入到鏈表的頭部。
  • JDK 1.8:鏈表插入使用的是尾插法。這是因為JDK 1.8在插入元素時需要判斷鏈表長度,尾插法便于統計鏈表元素個數。同時,尾插法也避免了頭插法可能導致的鏈表反轉問題。

3. 哈希算法的變化

  • JDK 1.7:哈希算法相對復雜,涉及多種右移和位運算操作。
  • JDK 1.8:哈希算法進行了簡化。這是因為JDK 1.8引入了紅黑樹,可以在一定程度上彌補簡化哈希算法可能帶來的散列性降低問題,從而節省CPU資源。

4. 擴容機制的變化

  • JDK 1.7:擴容時,會重新創建一個更大的數組,并將原數組中的元素逐個添加到新數組中。這個過程比較耗費時間和性能。
  • JDK 1.8:擴容機制得到了優化。當達到擴容條件時(容量*負載因子超過閾值),會創建一個大小為原數組兩倍的新數組,并采用更高效的方式遷移數據。此外,JDK 1.8還引入了“樹化”的概念,即在擴容時,鏈表長度達到閾值的桶會直接轉換為紅黑樹,以減少擴容操作的時間復雜度。

5. 并發性的改進

  • JDK 1.7:HashMap本身是非線程安全的,在多線程環境下使用時需要額外的同步機制來保證數據一致性。
  • JDK 1.8:雖然HashMap本身仍然是非線程安全的,但JDK 1.8通過一些機制(如synchronized關鍵字、CAS操作等)提高了其在多線程環境下的性能。然而,對于需要線程安全的場景,仍然建議使用ConcurrentHashMap。

代碼講解

下面是一些簡化的源碼片段和注釋,用于說明JDK 1.7和JDK 1.8中HashMap的關鍵部分。

JDK 1.7 HashMap 簡化源碼
// JDK 1.7 HashMap 的簡化版本
public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Serializable {// 省略了大部分成員變量和方法...// 存儲元素的數組transient Entry<K, V>[] table;// Entry 是 HashMap 的一個內部類,表示一個鍵值對static class Entry<K, V> implements Map.Entry<K, V> {final K key;V value;Entry<K, V> next;// 省略了構造方法和其它方法...}// 省略了其它方法...// put 方法(簡化版)public V put(K key, V value) {// 對 key 進行哈希運算,定位到數組中的某個位置int hash = hash(key);int i = indexFor(hash, table.length);// 遍歷鏈表,查看是否已存在相同的 keyfor (Entry<K, V> e = table[i]; e != null; e = e.next) {if (e.hash == hash && (e.key.equals(key) || key.equals(e.key))) {V oldValue = e.value;e.value = value;return oldValue;}}// 如果不存在,則添加新的 Entry 到鏈表中addEntry(hash, key, value, i);return null;}// 添加新的 Entry 到數組中(鏈表形式)void addEntry(int hash, K key, V value, int bucketIndex) {Entry<K, V> e = table[bucketIndex];table[bucketIndex] = new Entry<>(hash, key, value, e);// 如果數組中的元素數量超過閾值,則進行擴容if (size++ > threshold)resize(2 * table.length);}// 省略了其它方法...
}
JDK 1.8 HashMap 簡化源碼
// JDK 1.8 HashMap 的簡化版本
public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Serializable {// 省略了大部分成員變量和方法...// 存儲元素的數組(在 JDK 1.8 中,這個數組可能存儲 Node 或 TreeNode)transient Node<K, V>[] table;// Node 是 JDK 1.8 中新引入的一個內部類,用于替代 Entrystatic class Node<K, V> implements Map.Entry<K, V> {final int hash;final K key;V value;Node<K, V> next;// 省略了構造方法和其它方法...}// 當鏈表長度超過8時,會轉換為紅黑樹,TreeNode 是紅黑樹的一個節點static final class TreeNode<K, V> extends LinkedHashMap.Entry<K, V> {TreeNode<K, V> parent;TreeNode<K, V> left;TreeNode<K, V> right;TreeNode<K, V> prev;// 省略了紅黑樹相關的其它方法和成員變量...}// 省略了其它方法...// put 方法(簡化版)public V put(K key, V value) {return putVal(hash(key), key, value, false, true);}// 實際的 put 邏輯(簡化版)final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {Node<K, V>[] tab;Node<K, V> p;int n, i;// 如果數組為空,則進行初始化if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;// 定位到數組中的某個位置,如果為空則直接插入新的 Nodeif ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {// 如果不為空,則可能是鏈表或紅黑樹Node<K, V> e;K k;// 省略了部分邏輯,包括樹化處理和鏈表遍歷...// 如果找到了相同的 key,則更新 value 并返回舊值if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) {V oldValue = e.value;e.value = value;return oldValue;}// 如果沒找到相同的 key,則將新的 Node 插入到鏈表的末尾(或樹中)// 省略了具體的插入邏輯...}// 省略了其它邏輯,包括擴容和計數更新...return null;}// 省略了其它方法...
}

注釋說明

  • 在JDK 1.7中,HashMap使用Entry內部類來表示鍵值對,而在JDK 1.8中,引入了Node內部類來替代Entry
  • JDK 1.8中新增了TreeNode內部類,用于在鏈表長度超過8時將鏈表轉換為紅黑樹,以提高性能。
  • JDK 1.8中的put方法邏輯更加復雜,因為它需要處理鏈表和紅黑樹兩種情況。
  • 擴容機制在JDK 1.8中也有所改進,使得擴容過程更加平滑。

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

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

相關文章

RJ45 網線線序、E1線線序、2B+d線序

1、RJ45 網線線序 線序排列如下&#xff1a; T568A線序&#xff1a;綠白—1&#xff0c;綠—2&#xff0c;橙白—3&#xff0c;藍—4&#xff0c;藍白—5&#xff0c; 橙—6&#xff0c;棕白—7&#xff0c;棕—8 T568B線序&#xff1a;橙白—1&#xff0c;橙—2&#xff0c…

FreeBSD安裝教程

FreeBSD 是一個功能強大且可靠的開源 UNIX 操作系統&#xff0c;適合服務器和桌面環境。本文將介紹如何安裝 FreeBSD&#xff0c;從系統準備到基礎設置&#xff0c;為你快速上手提供幫助。 一、準備工作 1. 硬件要求 CPU&#xff1a;支持 x86 或 AMD64 架構的處理器。 內存&a…

Fortify_SCA_v24.2.0

前言 Fortify SCA 支持豐富的開發環境、語言、平臺和框架&#xff0c;可對開發與生產混合環境進行安全檢查。25 種編程語言 超過 911,000 個組件級 API 可檢測超過 961 個漏洞類別 支持所有主流平臺、構建環境和 IDE。 Fortify SCA是一款商業軟件&#xff0c;價格較為昂貴&am…

MyBatis框架的入門

目錄 MyBatis第一章&#xff1a;框架的概述1. MyBatis框架的概述 第二章&#xff1a;MyBatis的入門程序1. 創建數據庫和表結構2. MyBatis的入門步驟 MyBatis 第一章&#xff1a;框架的概述 1. MyBatis框架的概述 MyBatis是一個優秀的基于Java的持久層框架&#xff0c;內部對…

rust的axux框架開啟負載均衡和重啟自身的方法-會議簽到的調優

開啟負載均衡和重啟自身 更換axum后臺的意外解決的嘗試在caddy反代,使用負載均衡,加多一個節點axum主程序 ip映射信息做全局共享axum重啟自身刷新全局共享配置 前期剛實現了rust的后臺關鍵業務.結果出現了兩類大問題停止服務.在正用著的時候,出現很多意外,真是刺激… 更換axum…

深入理解數據庫索引:原理、分類與優化

目錄 1. 索引基礎1.1 索引的工作原理 2. 最左匹配原則2.1 什么是最左匹配原則&#xff1f;2.2 示例說明2.3 最左匹配原則的圖示 3. 索引分類3.1 按數據結構分類3.2 按索引列數分類3.3 按唯一性分類3.4 按存儲方式分類 4. 聚集索引與非聚集索引的區別4.1 聚集索引4.2 非聚集索引…

Three.js相機Camera控件知識梳理

原文&#xff1a;https://juejin.cn/post/7231089453695238204?searchId20241217193043D32C9115C2057FE3AD64 1. 相機類型 Three.js 主要提供了兩種類型的相機&#xff1a;正交相機&#xff08;OrthographicCamera&#xff09;和透視相機&#xff08;PerspectiveCamera&…

Bernstein-type inequality (BTI)

參見論文&#xff1a; Dual-Functional Artificial Noise (DFAN) Aided Robust Covert Communications in Integrated Sensing and Communications 理論 \boxed{} ?用于加框 Lemma 2. (BTI): For any A ∈ C N N \mathbf{A} \in\mathbb{C}^{N\times N} A∈CNN, b ∈ C N …

一條線上的點

給你一個數組 points &#xff0c;其中 points[i] [xi, yi] 表示 X-Y 平面上的一個點。求最多有多少個點在同一條直線上。 提示&#xff1a; 1 < points.length < 300points[i].length 2-104 < xi, yi < 104points 中的所有點 互不相同 解析&#xff1a;使用斜…

XX服務器上的npm不知道咋突然壞了

收到同事的V&#xff0c;說是&#xff1a;182上的npm不知道咋突然壞了&#xff0c;查到這里了&#xff0c;不敢動了。 咱一定要抓重點&#xff1a;突然壞了。這里的突然肯定不是瞬間&#xff08;大概率是上次可用&#xff0c;這次不可用&#xff0c;中間間隔了多長時間&#x…

GNSS定位局限性與綜合PNT及5G定位技術研究

摘要 本文主要介紹了GNSS定位技術的系統組成與原理、發展歷程、應用領域及現狀&#xff0c;并分析了其存在的局限性&#xff0c;如信號遮擋、多路徑效應、大氣層干擾等。文章還探討了綜合PNT技術的體系架構、多源信息融合方法以及智能化算法在PNT中的應用&#xff0c;強調了綜…

/hbase/oldWALs 文件

/hbase/oldWALs 是 HBase 中的一個目錄&#xff0c;用于存儲那些不再需要用于恢復目的的 WAL&#xff08;Write-Ahead Log&#xff09;文件。這些文件在 HBase 確認所有的數據都已經從 MemStore 持久化到 HFile 之后&#xff0c;會被移動到這個目錄。 /hbase/oldWALs 目錄中的…

HALCON 算子 之 形態學操作算子

文章目錄 什么是形態學操作&#xff1f;為什么要形態學操作&#xff1f;怎么形態學操作&#xff1f;腐蝕 —— Erosionerosion1erosion_circle&#xff1a;erosion_rectangle1&#xff1a; 膨脹 —— Dilationdilation1dilation_circledilation_rectangle1 打開 —— Openingop…

[金盾杯 2024] PWN 復現

好長時間不作題了&#xff0c;在復現平臺上看到這個比賽&#xff0c;作了一下&#xff0c;題過于簡單了。不過密碼一言難盡。 Orange 要說libc-2.23有多老&#xff0c;我一開始學PWN的時候還有不少&#xff0c;這兩年幾乎不見了。一些比賽估計是拿的舊題。 遠看像個堆題&…

pytest入門九:feature

fixture是pytest特有的功能&#xff0c;用以在測試執行前和執行后進行必要的準備和清理工作。使用pytest.fixture標識&#xff0c;定義在函數前面。在你編寫測試函數的時候&#xff0c;你可以將此函數名稱做為傳入參數&#xff0c;pytest將會以依賴注入方式&#xff0c;將該函數…

uniapp Vue3 語法實現瀏覽器中音頻錄制、停止、保存、播放、轉碼、實時音頻輸出

一、引言 在現代 Web 應用開發中,音頻處理功能變得越來越重要。本文將詳細介紹如何使用 uniapp 結合 Vue3 語法在瀏覽器環境中實現音頻錄制、停止、保存、播放、轉碼以及實時音頻輸出等一系列功能。通過深入剖析代碼結構和功能實現細節,幫助讀者全面理解和掌握相關技術,以便…

【jpa】會什么jpa會自動新建一個hibernate_sequence表

目錄 1. 說明2. 主鍵生成策略3. hibernate_sequence表的創建4. 如何避免自動創建hibernate_sequence表 1. 說明 1.JPA&#xff08;Java Persistence API&#xff09;在默認情況下&#xff0c;如果使用Hibernate作為持久化框架&#xff0c;并且沒有顯式指定主鍵生成策略&#x…

秒優科技-供應鏈管理系統 login/doAction SQL注入漏洞復現

0x01 產品簡介 秒優科技提供的供應鏈管理系統,即秒優SCM服裝供應鏈管理系統,是一款專為服裝電商企業設計的全方位解決方案。是集款式研發、訂單管理、物料管理、生產管理、工藝管理、收發貨管理、賬單管理、報表管理于一體的服裝電商供應鏈管理解決方案。它涵蓋了從企劃到開…

【TF-IDF】Hugging Face Model Recommendation System

利用了機器學習技術的模型檢索 TF-IDF (Term Frequency-Inverse Document Frequency) 文本特征提取例子This project is a Hugging Face Model Recommendation System designed to assist users in discovering the most suitable models based on their task descriptions. Th…

136.WEB滲透測試-信息收集-小程序、app(7)

免責聲明&#xff1a;內容僅供學習參考&#xff0c;請合法利用知識&#xff0c;禁止進行違法犯罪活動&#xff01; 內容參考于&#xff1a; 易錦網校會員專享課 上一個內容&#xff1a;135.WEB滲透測試-信息收集-小程序、app&#xff08;6&#xff09; 進入之后我們通過輸入…