精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

對(duì)比Java中HashMap的一些異同

科技綠洲 ? 來(lái)源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-09-30 10:46 ? 次閱讀

1.前言

我們回顧一下之前講到的Redis的字典結(jié)構(gòu),示意圖如下:

圖片

Redis的字典本質(zhì)上來(lái)說(shuō)也是數(shù)組+鏈表的數(shù)據(jù)結(jié)構(gòu),這與Java中HashMap的數(shù)據(jù)結(jié)構(gòu)很類似。

由上述結(jié)構(gòu)示意圖也能看出,字典dict中維護(hù)了一個(gè)ht數(shù)組,而且只有兩個(gè)元素,這兩個(gè)元素是其擴(kuò)容的關(guān)鍵點(diǎn),這個(gè)我們后面會(huì)講到。

Redis中的哈希對(duì)象在以下條件時(shí),使用ziplist編碼,

  • 哈希對(duì)象保存的所有鍵值的字符串長(zhǎng)度都小于64字節(jié)
  • 哈希對(duì)象保存的鍵值對(duì)數(shù)量小于512個(gè)。

否則哈希對(duì)象會(huì)使用hashtable編碼, 而hashtable則時(shí)使用了字典作為底層實(shí)現(xiàn)的。

如下redis 哈希對(duì)象編碼由ziplist 變成hashtable

圖片

2.增加元素與鍵沖突

當(dāng)不同的鍵值經(jīng)過(guò)哈希算法與散列算法之后被分配到了同一個(gè)哈希表數(shù)組的同一個(gè)索引上,那么這之后就會(huì)有鍵沖突。

Redis 哈希表解決哈希沖突同樣是使用了鏈表地址法。使用哈希節(jié)點(diǎn)的next指針來(lái)鏈接同一個(gè)哈希表數(shù)組索引上的元素。不過(guò)Redis會(huì)將新添加的哈希節(jié)點(diǎn)加入到鏈表的表頭位置。

如下所示:如果程序要將鍵值對(duì) (k2 , v2 ) 添加到如下的哈希表中,而且計(jì)算的書(shū)的索引為1,那么和 (k1 v1) 將產(chǎn)生沖突。解決沖突時(shí),會(huì)將兩個(gè)節(jié)點(diǎn)使用next指針鏈接起來(lái)。而且會(huì)將新節(jié)點(diǎn)添加到鏈表表頭的位置。

圖片
哈希表1

圖片
鏈表解決hash沖突之后的哈希表

3.rehash 擴(kuò)容過(guò)程

哈希表不斷的增加元素,其元素?cái)?shù)量達(dá)到一定的比例之后,程序會(huì)對(duì)哈希表進(jìn)行相應(yīng)的擴(kuò)展。通過(guò)執(zhí)行rehash (重新散列)操作完成操作。其步驟如下:

  • 執(zhí)行擴(kuò)展操作時(shí)會(huì)將字典中的ht[1] 哈希表大小設(shè)置成 第一個(gè)大于等于 ht[0] 的 ht[0].used * 2 的 2^n (2的n次冪)
  • 將保存早ht[0] 中的所有的鍵值對(duì) rehash到ht[1] 上, rehash過(guò)程中會(huì)重新計(jì)算哈希值和索引值。
  • 當(dāng)ht[0]中所有的鍵值對(duì)都遷移到ht[1]上時(shí),釋放ht[0], 并將ht[1] 設(shè)置成 ht[0], 并在ht[1]上建一個(gè)空的哈希表。

將下圖中的字典做rehash操作:

圖片

  1. ht[0].used 是4,4*2 = 8 ,2的3次方8 是第一個(gè)大于4 的 2的n次冪。即程序會(huì)將ht[1] 的大小設(shè)置成8 ,并分配空間,結(jié)構(gòu)示意如下:

圖片

  1. 將ht[0] 上的幾個(gè)鍵值對(duì)全部都rehash到ht[1] 上面,如下圖:

圖片

  1. 釋放ht[0],并將ht[1] 設(shè)置成 ht[0] , 然后為ht[1]分配一個(gè)空白的哈希表 如下圖:

圖片

以上是一個(gè)rehash的過(guò)程示意。

4.漸進(jìn)式rehash

上面講的是一個(gè)rehash的理論過(guò)程,redis實(shí)際操作時(shí)并不會(huì)一次將所有的遷移一次性完成。

如果鍵值對(duì)數(shù)量非常龐大,那么遷移過(guò)程必然需要花費(fèi)一點(diǎn)時(shí)間。由此可知,服務(wù)器也不可能一次將所有的鍵值對(duì)遷移,需要分多次,逐漸將ht[0] 里面的鍵值對(duì)遷移到ht[1]中,

其步驟如下:

  • 首先會(huì)給ht[1]分配內(nèi)存空間,此時(shí)redis字典擁有兩個(gè)哈希表
  • 字典中維護(hù)一個(gè)rehashidx的計(jì)數(shù)器,將其值設(shè)置為0,表示rehash工作開(kāi)始
  • 在rehash期間,程序依然可以進(jìn)行增刪改查的操作,除此之外還會(huì)順帶將ht[0]上 rehashidx索引上所有的鍵值對(duì)rehash到ht[1]上,rehash的工作完成后會(huì)將rehashidx的值加1
  • 隨著字典的操作,ht[0]上的所有鍵值全部都rehash到ht[1]上時(shí),程序會(huì)將rehashidx的值設(shè)為-1 ,表示rehash操作已經(jīng)完成

在漸進(jìn)式rehash的過(guò)程中,redis字典依然是可以進(jìn)行增刪改查的操作, 其中增加元素的時(shí)候會(huì)將元素直接保存到ht[1]中, 而刪除,查找,更新的操作會(huì)在兩個(gè)哈希表中進(jìn)行, 查找時(shí)會(huì)先在ht[0]中進(jìn)行查找,然后會(huì)在ht[1]中進(jìn)行查找。以上措施可以保證ht[0]中的元素只會(huì)減少,最終變成空表。

總結(jié)

Redis字典和Java中的HashMap的相似點(diǎn)和不同。

相似之處:

  1. 鍵值對(duì)存儲(chǔ):Redis 字典和 Java 的 HashMap 都是鍵值對(duì)存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu),它們可以通過(guò)鍵來(lái)快速查找對(duì)應(yīng)的值。
  2. 高效的查找:Redis 字典和 Java 的 HashMap 都使用了哈希表來(lái)實(shí)現(xiàn),因此在查找操作上具有高效性能。
  3. Redis 字典使用的時(shí)哈希表作為底層,并且每個(gè)字典維護(hù)了兩個(gè)哈希表,ht[0] 時(shí)主要使用的哈希表,而ht[1] 是在rehash過(guò)程是才會(huì)使用到的表。
  4. 哈希表的底層同樣是使用了數(shù)組 + 鏈表的結(jié)構(gòu), 與Java 中HashMap 相似,只不過(guò)Java8 以后增加了紅黑樹(shù),在特定情況下會(huì)替換鏈表。

不同之處:

  1. 哈希表增加元素遇到哈希沖突是會(huì)將新添加的元素放到鏈表頭,而Java HashMap會(huì)將其放到鏈表尾,
  2. 擴(kuò)容過(guò)程中redis的字典是漸進(jìn)式擴(kuò)容,擴(kuò)容期間還是可以進(jìn)行操作的,而Java的HashMap擴(kuò)容需要一次性完成。
  3. 存儲(chǔ)方式:Redis 字典是一種基于內(nèi)存的數(shù)據(jù)結(jié)構(gòu),用于在內(nèi)存中存儲(chǔ)鍵值對(duì)。而 Java 的 HashMap 可以在內(nèi)存中存儲(chǔ),也可以持久化到磁盤(pán)上。
  4. 分布式支持:Redis 是一種分布式數(shù)據(jù)庫(kù),可以在多臺(tái)服務(wù)器上進(jìn)行數(shù)據(jù)共享和存儲(chǔ)。而 Java 的 HashMap 只能在單個(gè) JVM 中使用。
  5. 數(shù)據(jù)類型:Redis 字典可以存儲(chǔ)多種數(shù)據(jù)類型,如字符串、列表、集合等,而 Java 的 HashMap 只能存儲(chǔ)對(duì)象類型。
  6. 持久化:Redis 字典可以將數(shù)據(jù)持久化到磁盤(pán)上,以便在重啟后恢復(fù)數(shù)據(jù)。而 Java 的 HashMap 需要自己實(shí)現(xiàn)數(shù)據(jù)的序列化和反序列化來(lái)實(shí)現(xiàn)持久化。
  7. 并發(fā)性:Redis 字典是線程安全的,可以支持多個(gè)客戶端并發(fā)訪問(wèn)。而 Java 的 HashMap 在多線程環(huán)境下需要進(jìn)行額外的同步處理才能保證線程安全。
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2960

    瀏覽量

    104557
  • 編碼
    +關(guān)注

    關(guān)注

    6

    文章

    935

    瀏覽量

    54765
  • 字符串
    +關(guān)注

    關(guān)注

    1

    文章

    577

    瀏覽量

    20488
  • 數(shù)據(jù)結(jié)構(gòu)

    關(guān)注

    3

    文章

    573

    瀏覽量

    40094
  • hashmap
    +關(guān)注

    關(guān)注

    0

    文章

    14

    瀏覽量

    2278
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    java集合干貨系列

    而不是數(shù)組  數(shù)組的長(zhǎng)度固定,集合長(zhǎng)度可變  數(shù)組只能通過(guò)下標(biāo)訪問(wèn)元素,類型固定,而有的集合可以通過(guò)任意類型查找所映射的具體對(duì)象。  整理的集合框架思維導(dǎo)圖  個(gè)人整理的Java集合框架思維導(dǎo)圖,動(dòng)態(tài)維護(hù)。導(dǎo)出的圖片無(wú)法查看備注的一些信息,所以需要源文件的童鞋可以回復(fù)郵箱
    發(fā)表于 12-14 15:11

    關(guān)于java性能優(yōu)化的一些細(xì)節(jié)

    代碼優(yōu)化 ,個(gè)很重要的課題。可能有些人覺(jué)得沒(méi)用,一些細(xì)小的地方有什么好修改的,改與不改對(duì)于代碼的運(yùn)行效率有什么影響呢?這個(gè)問(wèn)題我是這么考慮的,就像大海里面的鯨魚(yú)樣,它吃條小蝦米有
    發(fā)表于 10-11 09:23

    Java-4 Java的類

    關(guān)于JAVA入門的一些簡(jiǎn)明教程,還有一些簡(jiǎn)單的程序,適合入門PPT。
    發(fā)表于 04-29 11:28 ?0次下載

    JAVA關(guān)于this和that的一些知識(shí)

    新手在入門 Java 的過(guò)程定會(huì)踩很多關(guān)于 this 的坑,出現(xiàn)問(wèn)題的本質(zhì)就是 this 指針的指向和自己想的不樣。筆者在入門學(xué)習(xí)的過(guò)程
    發(fā)表于 09-25 14:55 ?0次下載

    關(guān)于Java HashMap的認(rèn)知

    HashMap詳解 HashMap 和 HashSet 是 Java Collection Framework 的兩個(gè)重要成員,其中 HashMap 是 Map 接口的常用實(shí)現(xiàn)類,Ha
    發(fā)表于 09-27 16:34 ?0次下載
    關(guān)于<b class='flag-5'>Java</b> <b class='flag-5'>HashMap</b>的認(rèn)知

    java異常處理設(shè)計(jì)和一些建議

    程序設(shè)計(jì)在程序設(shè)計(jì),進(jìn)行異常處理是非常關(guān)鍵和重要的部分。個(gè)程序的異常處理框架的好壞直接影響到整個(gè)項(xiàng)目的代碼質(zhì)量以及后期維護(hù)成本和難度。試想下,如果
    發(fā)表于 09-28 11:48 ?0次下載
    <b class='flag-5'>java</b>異常處理設(shè)計(jì)和<b class='flag-5'>一些</b>建議

    關(guān)于java一些基礎(chǔ)知識(shí)解析

    j2ee 全稱Java 2 Enterprise Edition,是Java種企業(yè)版,用于企業(yè)級(jí)應(yīng)用開(kāi)發(fā)。 j2se 全稱Java 2 Standard Edi
    的頭像 發(fā)表于 02-05 14:43 ?4748次閱讀
    關(guān)于<b class='flag-5'>java</b>的<b class='flag-5'>一些</b>基礎(chǔ)知識(shí)解析

    十個(gè)問(wèn)題帶你了解和掌握java HashMap

    本文檔內(nèi)容介紹了十個(gè)問(wèn)題帶你了解和掌握java HashMap及源代碼,供參考
    發(fā)表于 03-12 15:41 ?0次下載

    java學(xué)習(xí)—探秘Java的String、StringBuilder以及StringBuffer

    探秘JavaString、StringBuilder以及StringBuffer 相信String這個(gè)類是Java中使用得最頻繁的類之,并且又是各大公司面試喜歡問(wèn)到的地方,今天就來(lái)
    發(fā)表于 03-13 10:58 ?0次下載

    Java一些基礎(chǔ)面試題資料合集免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是Java一些基礎(chǔ)面試題資料合集免費(fèi)下載。目錄,1.Java基礎(chǔ)知識(shí)篇 2.Java web基礎(chǔ)知識(shí)總結(jié) 3.Java
    發(fā)表于 05-10 18:13 ?0次下載
    <b class='flag-5'>Java</b>的<b class='flag-5'>一些</b>基礎(chǔ)面試題資料合集免費(fèi)下載

    寫(xiě)Java代碼的一些技巧分享

    有時(shí)候我們?yōu)榱私y(tǒng)管理會(huì)把一些變量放到 yml 配置文件
    的頭像 發(fā)表于 03-16 12:05 ?1328次閱讀

    學(xué)習(xí)linux內(nèi)核的一些建議

    學(xué)習(xí)linux內(nèi)核,這個(gè)可不像學(xué)門語(yǔ)言,c或者java個(gè)月或者3月你就能精通掌握。學(xué)習(xí)linux內(nèi)核是需要步循序漸進(jìn),掌握正確的l
    發(fā)表于 05-07 15:20 ?610次閱讀
    學(xué)習(xí)linux內(nèi)核的<b class='flag-5'>一些</b>建議

    介紹一些大功率IGBT模塊應(yīng)用一些技術(shù)

    PPT主要介紹了大功率IGBT模塊應(yīng)用一些技術(shù),包括參數(shù)解讀、器件選型、驅(qū)動(dòng)技術(shù)、保護(hù)方法以及失效分析等。
    發(fā)表于 09-05 11:36 ?783次閱讀

    runtime 的一些對(duì)比選型和應(yīng)用

    基于 io-uring 為 Rust 提供異步支持,并在此基礎(chǔ)上研發(fā)通用網(wǎng)關(guān)。 本文包括以下內(nèi)容: 介紹 Rust 異步 Runtime; Monoio 的一些設(shè)計(jì)精要; Runtime 對(duì)比選型與應(yīng)用。 02 Rust
    的頭像 發(fā)表于 05-26 15:48 ?623次閱讀
    runtime 的<b class='flag-5'>一些</b><b class='flag-5'>對(duì)比</b>選型和應(yīng)用

    java中常用的包有哪些

    Java種面向?qū)ο蟮母呒?jí)編程語(yǔ)言,它具有平臺(tái)無(wú)關(guān)性和可擴(kuò)展性。Java中有很多常用的包,這些包提供了豐富的類庫(kù)和工具,用于開(kāi)發(fā)各種類型的應(yīng)用程序。下面是Java
    的頭像 發(fā)表于 11-22 15:10 ?1324次閱讀