最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

HashMap中哈希值與數(shù)組坐標的關(guān)聯(lián)方式

 更新時間:2025年05月13日 10:11:39   作者:找不到、了  
這篇文章主要介紹了HashMap中哈希值與數(shù)組坐標的關(guān)聯(lián)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

在 HashMap 中,通過對鍵的哈希值進行處理,能夠?qū)⑸傻墓4a映射到 HashMap 內(nèi)部數(shù)組(桶)中的索引位置。

如下圖所示:

這一過程可以通過以下步驟認真分析:

想了解更多map數(shù)據(jù)結(jié)構(gòu)更多的可參考:HashMap的擴容機制

1、哈希值的生成與處理

如我們之前討論的,第一次會調(diào)用 hashCode() 方法來生成一個完整的 32 位整數(shù)哈希碼。然后,使用以下代碼對哈希值進行處理:

int h = key.hashCode();
h ^= (h >>> 16);

2、計算桶的索引

經(jīng)過處理后,哈希值可能會更分散,最后會用于計算桶的索引位置:

int index = h & (n - 1);

2.1 這里的計算方法:

  • n 是當前 HashMap 內(nèi)部數(shù)組的長度(即桶的數(shù)量)。為了更高效地計算數(shù)組索引,我們通常選擇 n 為 2 的冪(例如 16、32、64 等),這允許高效的位操作。
  • n - 1 的計算是為了確保采用位與運算來進行取模操作。例如,如果 n 為 16(即 10000),那么 n - 1 為 15(即 01111)。這樣做的好處是通過位與運算能夠快速計算出在數(shù)組中的有效索引。

2.2 示例

假設(shè)生成的哈希值 h0b11010110110101101010011000111101(即 32 位二進制數(shù)),并且 HashMap 的桶數(shù)量 n 為 16(也即 index = h & 15)。

計算過程:

  • 二進制示例哈希值:11010110110101101010011000111101
  • n-100000000000000000000000000001111 (即 15 的二進制表示)

進行位與操作:

        11010110110101101010011000111101
  &     00000000000000000000000000001111
  ------------------------------------------
        00000000000000000000000000000101  (結(jié)果即為 index)
  • 結(jié)果 index 是 5,表示該鍵值對應的元素存放在 HashMap 的第 5 個桶(數(shù)組索引為 5 的位置)。

3、哈希值總結(jié)

  • 哈希值處理:通過對原始哈希碼的處理(即與高位信息進行異或),可以確保更均勻的哈希分布,從而減少碰撞的機會。
  • 桶的索引計算:使用 h & (n - 1) 技巧使得計算過程高效,將生成的哈希值直接映射到 HashMap 內(nèi)部數(shù)組的有效索引,從而實現(xiàn)快速的鍵值對存儲和檢索。
  • 效率:以上步驟都是為了確保在 O(1) 平均情況下能快速訪問 HashMap 中的元素,同時減少由于哈希沖突引起的性能損失。

4、哈希沖突解決方案

拉鏈法(Separate Chaining)和開放尋址法(Open Addressing)是兩種常用的哈希表沖突解決策略。

它們在處理兩個或多個鍵沖突(即哈希函數(shù)返回相同索引)時采取不同的策略。

下面是對這兩種方法的詳細介紹及示例:

4.1. 拉鏈法(Separate Chaining)

1.原理

基本思路是為每個哈希表的桶(數(shù)組索引)維護一個鏈表(或其他數(shù)據(jù)結(jié)構(gòu)),用來存儲所有哈希到同一索引位置的鍵值對。當發(fā)生沖突時,新的鍵值對會被追加到這個鏈表中。

2.特點

  • 沖突分離:拉鏈法可以有效處理沖突,因為每個桶可以容納多個元素。
  • 空間利用率:空間利用率較高,尤其在負載因子較大時。

3.示例

設(shè)想一個簡單的哈希表,哈希函數(shù)為 h(key) = key mod 5,并且存在以下鍵值對:

  • (3, "A")
  • (8, "B")
  • (13, "C")
  • (9, "D")

哈希表的桶數(shù)組將如下所示(使用鏈表處理沖突):

Index: 0  -> null
Index: 1  -> null
Index: 2  -> null
Index: 3  -> (3, "A") -> null
Index: 4  -> (8, "B") -> null

當插入鍵 13,計算得到 h(13) = 3,這個鍵會追加到索引 3 的鏈表中:

Index: 0  -> null
Index: 1  -> null
Index: 2  -> null
Index: 3  -> (3, "A") -> (13, "C") -> null
Index: 4  -> (8, "B") -> null

4.2. 開放尋址法(Open Addressing)

1.原理

開放尋址法在發(fā)生哈希沖突時,會在哈希表的數(shù)組中尋找下一個可用的桶來存儲沖突的元素。

常用的方法包括線性探測、二次探測和雙重哈希等。

2.特點

  • 使用數(shù)組存儲數(shù)據(jù):所有數(shù)據(jù)都存儲在哈希表的原始數(shù)組中,不需要額外的鏈表或其他數(shù)據(jù)結(jié)構(gòu)。
  • 查找時間:在平均情況下,查找時間復雜度與負載因子密切相關(guān),負載因子過高可能導致性能下降。

3.示例

仍然使用相同的哈希函數(shù) h(key) = key mod 5,并且存在以下鍵值對:

  • (3, "A")
  • (8, "B")
  • (9, "D")

假設(shè)當前哈希表的索引結(jié)構(gòu)如下:

Index: 0  -> null
Index: 1  -> null
Index: 2  -> null
Index: 3  -> (3, "A") 
Index: 4  -> (8, "B") 

當插入鍵 9 時,計算得到 h(9) = 4,但索引 4 已經(jīng)被占用,因此會采取開放尋址法策略查找下一個可用位置。這個位置是索引 0(線性探測),最終得到如下數(shù)據(jù)結(jié)構(gòu):

Index: 0  -> (9, "D")
Index: 1  -> null
Index: 2  -> null
Index: 3  -> (3, "A") 
Index: 4  -> (8, "B") 

常用的探測方法

1、線性探測(Linear Probing)

  • 當發(fā)生沖突時,逐個檢查下一個可用的桶。通過簡單地向后移動(對當前索引加 1)來查找下一個位置。
  • 例如,如果索引 ii 已經(jīng)被占用,就檢查 (i+1)(i+1), (i+2)(i+2),...直到找到空桶。

這種方法的實現(xiàn)如下:

public int linearProbe(int hash, int i) {
    return (hash + i) % table.length;
}

2、二次探測(Quadratic Probing)

    • 對于每次沖突,使用二次函數(shù)(例如,i2i2)的方式查找下一個位置。這有助于減少碰撞和聚集問題。
    • 例如,如果索引 ii 已經(jīng)被占用,就檢查 (i+12)(i+12),(i+22)(i+22),(i+32)(i+32),...直到找到空桶。

    實現(xiàn)類似于:

    public int quadraticProbe(int hash, int i) {
        return (hash + i * i) % table.length;
    }

    3、雙重哈希(Double Hashing)

    • 兩個不同的哈希函數(shù)同時使用,第一次利用主哈希函數(shù)獲取初步的索引,若發(fā)生沖突,則根據(jù)第二個哈希函數(shù)計算步長。這種方法能夠減小聚集問題。
    • 例如,如果主哈希函數(shù)返回的索引 h1h1,而第二個哈希函數(shù)返回 h2h2,那么如果發(fā)生沖突,查找下一個位置的方法為:
    public int doubleHash(int hash, int i) {
        return (hash + i * secondHash(key)) % table.length;
    }

    心得

    在開放尋址法中,探測的基礎(chǔ)是通過某種方式計算下一個桶的索引,從而避免沖突并正確處理數(shù)據(jù)。

    每種探測方法(線性、二次、雙重)各有優(yōu)缺點,實際使用時可以根據(jù)應用需求、性能和負載因子來選擇合適的探測方式。

    總結(jié)

    以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

    相關(guān)文章

    • 詳解Java解析XML的四種方法

      詳解Java解析XML的四種方法

      本篇文章主要介紹了java解析XML的幾種方式,XML現(xiàn)在已經(jīng)成為一種通用的數(shù)據(jù)交換格式,給數(shù)據(jù)集成與交互提供了方便,有需要的可以了解一下。
      2016-11-11
    • Java中冒泡排序的原生實現(xiàn)方法(正序與逆序)

      Java中冒泡排序的原生實現(xiàn)方法(正序與逆序)

      這篇文章主要給大家介紹了關(guān)于Java中冒泡排序的原生實現(xiàn)方法(正序與逆序)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
      2020-11-11
    • Java設(shè)計模式之命令模式(Command模式)介紹

      Java設(shè)計模式之命令模式(Command模式)介紹

      這篇文章主要介紹了Java設(shè)計模式之命令模式(Command模式)介紹,本文講解了Command模式的定義、如何使用命令模式等內(nèi)容,需要的朋友可以參考下
      2015-03-03
    • SpringBoot各種參數(shù)校驗的實例教程

      SpringBoot各種參數(shù)校驗的實例教程

      經(jīng)常需要提供接口與用戶交互(獲取數(shù)據(jù)、上傳數(shù)據(jù)等),由于這個過程需要用戶進行相關(guān)的操作,為了避免出現(xiàn)一些錯誤的數(shù)據(jù)等,一般需要對數(shù)據(jù)進行校驗,下面這篇文章主要給大家介紹了關(guān)于SpringBoot各種參數(shù)校驗的相關(guān)資料,需要的朋友可以參考下
      2022-03-03
    • 淺談SpringBoot中的Bean初始化方法?@PostConstruct

      淺談SpringBoot中的Bean初始化方法?@PostConstruct

      這篇文章主要介紹了SpringBoot中的Bean初始化方法?@PostConstruct,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
      2021-11-11
    • java稀疏數(shù)組的示例代碼

      java稀疏數(shù)組的示例代碼

      這篇文章主要介紹了java稀疏數(shù)組,稀疏數(shù)組,記錄一共有幾行幾列,有多少個不同值,把具有不同值的元素和行里了及值記錄在一個小規(guī)模的數(shù)組中,從而縮小程序的規(guī)模,對java稀疏數(shù)組相關(guān)知識感興趣的朋友一起看看吧
      2022-07-07
    • RocketMQ中消費者概念和消費流程詳解

      RocketMQ中消費者概念和消費流程詳解

      這篇文章主要介紹了RocketMQ中消費者概念和消費流程詳解,RocketMQ是一款高性能、高可靠性的分布式消息中間件,消費者是RocketMQ中的重要組成部分,消費者負責從消息隊列中獲取消息并進行處理,需要的朋友可以參考下
      2023-10-10
    • 詳細了解java監(jiān)聽器和過濾器

      詳細了解java監(jiān)聽器和過濾器

      下面小編就為大家?guī)硪黄趈ava servlet過濾器和監(jiān)聽器(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
      2021-07-07
    • Mybatis-plus批量插入的2種方式總結(jié)

      Mybatis-plus批量插入的2種方式總結(jié)

      這篇文章主要給大家總結(jié)介紹了關(guān)于Mybatis-plus批量插入的2種方式,Mybatis-Plus提供了多種方式進行批量插入優(yōu)化,文中通過代碼示例將實現(xiàn)的方法介紹的非常詳細,需要的朋友可以參考下
      2023-08-08
    • java集合中l(wèi)ist的用法代碼示例

      java集合中l(wèi)ist的用法代碼示例

      這篇文章主要介紹了java集合中l(wèi)ist的用法代碼示例,分享了相關(guān)代碼,具有一定參考價值,需要的朋友可以了解下。
      2017-11-11

    最新評論

    安溪县| 通海县| 织金县| 芮城县| 五莲县| 锡林浩特市| 拉孜县| 宿州市| 中西区| 马尔康县| 西青区| 明水县| 柳江县| 长宁县| 鸡东县| 梅河口市| 治县。| 镇坪县| 民和| 集安市| 武隆县| 衡南县| 惠州市| 子洲县| 阿瓦提县| 临汾市| 伊通| 安福县| 青龙| 泽库县| 玉溪市| 招远市| 宿州市| 高碑店市| 崇州市| 肃宁县| 尼木县| 元谋县| 巴塘县| 小金县| 博湖县|