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

淺談hashmap為什么查詢時(shí)間復(fù)雜度為O(1)

 更新時(shí)間:2021年08月02日 08:48:48   作者:PolarisHuster  
這篇文章主要介紹了hashmap為什么查詢時(shí)間復(fù)雜度為O(1),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

hashmap為什么查詢時(shí)間復(fù)雜度為O(1)

Hashmap是java里面一種類字典式數(shù)據(jù)結(jié)構(gòu)類,能達(dá)到O(1)級(jí)別的查詢復(fù)雜度,那么到底是什么保證了這一特性呢,這個(gè)就要從hashmap的底層存儲(chǔ)結(jié)構(gòu)說起

下來看一張圖:

上面就是hashmap的底層存儲(chǔ)示意圖,要想查看一個(gè)鍵值對(duì)應(yīng)的值,首先根據(jù)該鍵值的hash值找到該鍵的hash桶位置,即是tab[2]還是tab[1]等,計(jì)算某個(gè)鍵對(duì)應(yīng)的哈希桶位置很簡(jiǎn)單,就是

int pos = (n - 1) & hash,也就是hash%n,因?yàn)槲贿\(yùn)算效率高所以在hashmap實(shí)現(xiàn)時(shí)使用的是位運(yùn)算這種方式,需要注意的是哈希桶的數(shù)量必須是2^n,所以hashmap一旦擴(kuò)容必定是哈希桶數(shù)量翻番。

通過上面的描述,我們可以知道,根據(jù)鍵值找到哈希桶的位置時(shí)間復(fù)雜度為O(1),使用的就是數(shù)組的高效查詢。但是僅僅有這個(gè)是無法滿足整個(gè)hashmap查詢時(shí)間復(fù)雜度為O(1)的。hashmap在處理哈希沖突的方式如上圖所示的拉鏈法,在沖突數(shù)據(jù)沒有達(dá)到8個(gè)以前該哈希桶內(nèi)部存儲(chǔ)使用的是鏈表的方式,當(dāng)某個(gè)哈希桶的數(shù)據(jù)超過8個(gè)的情況下,

有下面兩種處理方式:

1、哈希桶的數(shù)量是沒有超過64個(gè),那么此時(shí)哈希桶數(shù)量double,然后數(shù)據(jù)遷移

2、哈希桶的數(shù)量超過了64個(gè),將該哈希桶內(nèi)部數(shù)據(jù)進(jìn)行紅黑樹化處理

所以我們可以看到如果所有哈希桶內(nèi)部數(shù)據(jù)都是鏈表存儲(chǔ)的,那么每個(gè)哈希桶的數(shù)據(jù)量不會(huì)超過8個(gè),這樣當(dāng)定位到某個(gè)哈希桶時(shí),在該哈希桶繼續(xù)查找也可以在O(1)時(shí)間內(nèi)完成,下面看一種極端情況,所有的數(shù)據(jù)都在同一個(gè)桶里面(這種情況只在所有鍵值hash值相同的情況下,這種情況下查詢的時(shí)間復(fù)雜度為O(lgn),比如下面給出的一個(gè)類,所有我們?cè)谠O(shè)置hashmap的鍵值時(shí)需要特別注意),在hashmap的文檔里面有這么一段描述,每個(gè)哈希桶中元素?cái)?shù)量是成泊松分布的,

listSize = (exp(-0.5) * pow(0.5, k) / * factorial(k)),

不同數(shù)量出現(xiàn)的概率如下:

* 0:    0.60653066
* 1:    0.30326533
* 2:    0.07581633
* 3:    0.01263606
* 4:    0.00157952
* 5:    0.00015795
* 6:    0.00001316
* 7:    0.00000094
* 8:    0.00000006
大于8: <千萬分之1

通過上面的統(tǒng)計(jì)來看,hashmap的鍵值正常(不同對(duì)象的hash值不同的情況),哈希桶數(shù)量超過8個(gè)概率低于千萬分之一,所以我們通常認(rèn)為hashmap的查詢時(shí)間復(fù)雜度為O(1)

PS:

1、哈希沖突百分百的類

 /**
    測(cè)試哈希沖突的類,所有的對(duì)象都返回同樣的hash值
   **/
    public static class Student{
        private String name;
        Student(String name){
            this.name = name;
        }
 
        @Override
        public int hashCode(){
            return 1;
        }
 
        @Override
        public boolean equals(Object obj){
            if(this == obj){
                return true;
            }
            if(obj == null){
                return false;
            }
            return this.name.equals(((Student)obj).name);
        }
    }

2、我們?cè)趯?shí)際使用hashmap時(shí)需要確保實(shí)現(xiàn)hashcode方法以及equals方法,否則不能作為hashmap的鍵值

3、在設(shè)置hashmap的鍵值hashcode方法時(shí)盡量保證較好的離散型

4、hashmap的鍵值需保證equals方法返回true時(shí),hashcode必須相同,所以在實(shí)際中經(jīng)常使用的鍵值類string,重寫了equals以及hashcode方法

HashMap時(shí)間復(fù)雜度問題

HashMap底層采用了hash算法

根據(jù) key 獲得 hashCode 值

HashMap 初始有很多個(gè)類似于“桶”的數(shù)據(jù)結(jié)構(gòu),比如說預(yù)設(shè)了 10 個(gè)桶,通過 hashCode 經(jīng)過一定的算法(這個(gè)算法必須是快速的)

得到這個(gè) hashCode 應(yīng)存在哪個(gè)桶中,然后內(nèi)部生成 Map.Entry 對(duì)象將 key 和 value 存到桶中去。

所以一般情況下HashMap的插入和查找的時(shí)間復(fù)雜度都是O(1);

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

相關(guān)文章

  • Springboot整合GuavaCache緩存過程解析

    Springboot整合GuavaCache緩存過程解析

    這篇文章主要介紹了springboot整合GuavaCache緩存過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Java中ArrayList和LinkedList之間的區(qū)別_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java中ArrayList和LinkedList之間的區(qū)別_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要為大家詳細(xì)介紹了Java中ArrayList和LinkedList之間的區(qū)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Spring條件注解用法案例分析

    Spring條件注解用法案例分析

    這篇文章主要介紹了Spring條件注解用法,結(jié)合具體實(shí)例形式分析了Spring條件注解相關(guān)原理、使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2019-11-11
  • springboot配置flyway(入門級(jí)別教程)

    springboot配置flyway(入門級(jí)別教程)

    本文介紹了springboot配置flyway,主要介紹基于SpringBoot集成flyway來管理數(shù)據(jù)庫(kù)的變更,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • Java中關(guān)于文件路徑讀取問題的分析

    Java中關(guān)于文件路徑讀取問題的分析

    今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識(shí),文章圍繞著Java中關(guān)于文件路徑讀取問題展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • MyBatisPlus代碼生成器的原理及實(shí)現(xiàn)詳解

    MyBatisPlus代碼生成器的原理及實(shí)現(xiàn)詳解

    這篇文章主要為大家詳細(xì)介紹了MyBatisPlus中代碼生成器的原理及實(shí)現(xiàn),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)MyBatisPlus有一定幫助,需要的可以參考一下
    2022-08-08
  • Springboot @Transactional使用時(shí)需注意的幾個(gè)問題記錄

    Springboot @Transactional使用時(shí)需注意的幾個(gè)問題記錄

    本文詳細(xì)介紹了Spring Boot中使用`@Transactional`注解進(jìn)行事務(wù)管理的多個(gè)方面,包括事務(wù)的隔離級(jí)別(如REPEATABLE_READ)和傳播行為(如REQUIRES_NEW),并指出了在同一個(gè)類中調(diào)用事務(wù)方法時(shí)可能遇到的問題以及解決方案,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • Mybatis 中的sql批量修改方法實(shí)現(xiàn)

    Mybatis 中的sql批量修改方法實(shí)現(xiàn)

    在項(xiàng)目中遇到需要批量更新的功能,原本想的是在Java中用循環(huán)訪問數(shù)據(jù)庫(kù)去更新,但是心里總覺得這樣做會(huì)不會(huì)太頻繁了,太耗費(fèi)資源了,效率也很低,查了下mybatis的批量操作,原來確實(shí)有<foreach>標(biāo)簽可以做到,下面通過本文給大家介紹下
    2017-01-01
  • JAVA加密算法- 非對(duì)稱加密算法(DH,RSA)的詳細(xì)介紹

    JAVA加密算法- 非對(duì)稱加密算法(DH,RSA)的詳細(xì)介紹

    這篇文章主要介紹了JAVA加密算法- 非對(duì)稱加密算法(DH,RSA),詳細(xì)介紹了DH,RSA的用法和示例,需要的朋友可以了解一下。
    2016-11-11
  • java數(shù)據(jù)結(jié)構(gòu)圖論霍夫曼樹及其編碼示例詳解

    java數(shù)據(jù)結(jié)構(gòu)圖論霍夫曼樹及其編碼示例詳解

    這篇文章主要為大家介紹了java數(shù)據(jù)結(jié)構(gòu)圖論霍夫曼樹及其編碼示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-11-11

最新評(píng)論

璧山县| 芦溪县| 宝丰县| 汝州市| 修武县| 安康市| 海晏县| 滨海县| 抚松县| 喀喇沁旗| 孝感市| 青岛市| 麻城市| 梁山县| 农安县| 西城区| 贺州市| 玛多县| 茂名市| 湖州市| 班玛县| 湖南省| 衡山县| 上栗县| 屏东市| 伊吾县| 宣城市| 碌曲县| 嘉禾县| 高尔夫| 临颍县| 金山区| 城口县| 阿拉尔市| 宜阳县| 广南县| 阳山县| 台北市| 讷河市| 周口市| 兴义市|