hashMap、ConcurrentHashMap、hashTable、TreeMap、LinkedHashMap用法區別詳解

来源:https://www.cnblogs.com/w001/archive/2022/04/22/16179475.html
-Advertisement-
Play Games

Java集合中設計了一個介面Java.util.Map,它實現類中hashMap、hashTable、TreeMap、ConcurrentHashMap、LinkedHashMap。 Map類型的集合用來做鍵值對存儲的,也就是key-value形式的。所以不允許鍵重覆,值是可以重覆的。 hashMa ...


  1. Java集合中設計了一個介面Java.util.Map,它實現類中hashMaphashTableTreeMapConcurrentHashMapLinkedHashMap
  2. Map類型的集合用來做鍵值對存儲的,也就是key-value形式的。所以不允許鍵重覆,值是可以重覆的。

hashMap

  1. hashMap 底層結構是:數組+鏈表+紅黑樹(jdk1.8之前就是存儲的數組+鏈表)

    說明:

     數組的特點:查詢效率高,插入,刪除效率低。
     鏈表的特點:查詢效率低,插入刪除效率高。
     在HashMap底層使用數組加(鏈表+紅黑樹)的結構完美的解決了數組和鏈表的問題,使得查詢和插入,刪除的效率都很高。
     當鏈表的長度達到某個閥值(8)的時候,這個鏈表就將轉換成紅黑樹。
     刪除的時候可能導致紅黑樹轉換為鏈表
     擴容也可能導致紅黑樹轉化為鏈表 擴容有可能導致紅黑樹拆成兩部分, 在這兩部分中, 任意部分, 如果元素數量是小於等於6的話, 會由紅黑樹轉化為鏈表。
     在jdk1.8中,如果鏈表長度大於8且節點數組長度大於64的時候,就把鏈表下所有的節點轉為紅黑樹。樹形化還有一個要求就是數組長度必須大於等於64,否則繼續採用擴容策略
    
  2. 預設初始容量16, 負載因數0.75,擴容機制是原容量的2倍。且要求容量一定為2的整數次冪

    說明:用數組容量大小乘以負載因數得到一個值,當數組中存儲的元素個數超過該值就會調用rehash方法將數組容量增加到原來的兩倍。在擴容的時候會生成一個新的數組,原來的所有數據需要重新計算哈希碼值重新分配到新的數組,所以擴容的操作非常消耗性能.

  3. 無序的,允許存null(鍵,值),線程不安全的。可以使用 Collections的synchronizedMap方法保證安全

  4. 存儲過程
    說明:存儲數據時計算KeyhashCode值%數組的長度得到對應的數組下標,如果這個下標沒有值就直接存入,如果有值就會計算euqals()的值是不是相等,相等就覆蓋,不相等就往下鏈。鏈的太多時會轉換為紅黑樹。

LinkedHashMap

  1. LinkedHashMap是HashMap一個子類,基本完全復用和遵從HashMap的特點
  2. LinkedHashMap在HashMap的基礎上維護了一個雙向鏈表,意味著他是有序的。

TreeMap

  1. TreeMap它是基於紅黑樹的NavigableMap實現。(樹中的每個節點的值都會大於或等於它的左子樹中的所有節點的值,並且小於或等於它的右子樹中的所有節點的值),實現了SortMap介面,能夠對保存的記錄根據鍵進行排序。
  2. 不允許NULL(鍵,值),線程不安全的
  3. 在TreeMap中存儲數據時, key-value, 我們可以有兩種方式: 一個就是讓key本身可以比較(繼承Comparable介面實現compareTo) 另一個就是可以在創建TreeMap的時候手動提供一個比較器

HashTable

  1. 無序,線程安全的(幾乎所有的方法都加鎖),不能存儲null值,null鍵
  2. 底層結構是數組+鏈表
  3. 預設初始容量11,擴容時2倍+1。且不要求底層數組的容量一定要為2的整數次冪;

ConcurrentHashMap

  1. ConcurrentHashMap 是線程安全的,相比較HashTable,jdk1.8之前ConcurrentHashMap是分段鎖(Segment),繼承了ReentrantLock。jdk1.8開始線程安全性由synchronized 和 CAS 來保證。
  2. ConcurrentHashMap可以一邊更新、一邊遍歷,也就是說在遍歷的時候,ConcurrentHashMap也可以進行remove,put操作,且遍歷的數據會隨著remove,put操作產生變化。HashTable會拋異常。
  3. get方法沒有加鎖,remove put是要加鎖的。
    說明:jdk1.8之前是分段鎖,一般不會出現鎖的爭搶,jdk1.8開始分的更細了,使用cas機制添加到樹的頭節點,如果失敗了,說明有其他線程在操作,那就再次迴圈上一步添加操作。如果頭節點已經存在了,通過synchronized獲得頭節點鎖,進行後續的操作。

總結

  1. 平常使用HashMap,訪問速度快,效率高。
  2. 排序需求的,並且需要自定義排序規則的使用TreeMap。
  3. 線程安全併發的需求時考慮使用ConcurrentHashMap。
  4. 需要快速增刪改查而且需要保證遍歷和插入順序一致的存儲功能 LinkedHashMap。

補充

  1. 二叉樹
    特點:左子節點的值小於父節點,右子節點的值大於父子節點。當有序列表時,會變成鏈表結構
  2. 平衡二叉樹 AVL
    特點:和二叉樹唯一不同的就是左子節點和右子節點的高度差最多等於1。
  3. 紅黑樹
    特點:通過左旋或者右旋維持樹的平衡,因為AVL太嚴格,當樹的節點發生變化時會破壞平衡。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Mybatis系列目標:從入門開始開始掌握一個高級開發所需要的Mybatis技能。 這是mybatis系列第10篇,源碼位於文章尾部! mybatis中一個比較強大的功能就是動態sql,記得在剛開始工作那會,當時使用jdbc開發系統,在java代碼中搞了很多判斷去拼接sql,代碼看起來比較亂,也不方 ...
  • 一晃今年又開始了,作為一個失意的中年技術男,現在的心境真的是五味雜陳。趕緊寫一篇吧,我怕過了這個點,今年就在沒有那個心情去寫了。 因為是基礎嘛,從事軟體開發以來c或者c++相關的東西斷斷續續 也刷了差不多一遍。中間看的書差不多有 c++游戲編程入門教程,vc++深入詳解, c++ primer pl ...
  • 1、錯誤內容:Could not resolve dependencies for project 今天在使用mvn clean package命令對一個子項目打包的時候出現如下錯誤(但是使用maven插件卻沒有問題) Failed to execute goal on project xxxx: ...
  • 快速排序 快速排序可能是應用最廣泛的演算法了。快排流行的原因在於實現簡單、並且適用於各種不同的輸入數據,因此在一般的應用中比其他排序演算法都要快很多。快排的優點在於其是原地排序,不向歸併至少需要建立一個和排序數組大小一樣的數組,並且快排的時間複雜度和NlgN成正比 基本思想 快速排序是一種分治的排序演算法 ...
  • package com.oop.demo02;//學生類public class Student { //屬性:欄位 String name; int age; //方法 public void study(){ System.out.println(this.name+"在學習"); } /* p ...
  • 問題 回答 xxljob支持自定義http介面來添加調度任務嗎? . 支持的,我們基於低代碼的實際場景,封裝成了openfeign的介面,這實際上也是一種http介面,我們封裝了兩個介面,一個用來增加和更新調度任務,一個用來修改任務的狀態,即啟用,停用,刪除; xxljob是否支持某個時間點固定執行 ...
  • Socks實際上是什麼:實際上是提供了精彩通信的埠,在通信之前雙方都必須要創造一個端點才能通信,其實感覺socket跟電腦的三次握手有些相似,分為三個步驟: (1)伺服器監聽 (2)客戶端請求 (3)連接確認 ...
  • 當你需要一個方法,可以簡便的遷移或複製虛擬環境到其他電腦上時,可以使用這個腳本一鍵創建虛擬環境並分享給你的朋友。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...