亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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

下來看一張圖:

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

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

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

有下面兩種處理方式:

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

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

所以我們可以看到如果所有哈希桶內(nèi)部數(shù)據(jù)都是鏈表存儲的,那么每個哈希桶的數(shù)據(jù)量不會超過8個,這樣當(dāng)定位到某個哈希桶時,在該哈希桶繼續(xù)查找也可以在O(1)時間內(nèi)完成,下面看一種極端情況,所有的數(shù)據(jù)都在同一個桶里面(這種情況只在所有鍵值hash值相同的情況下,這種情況下查詢的時間復(fù)雜度為O(lgn),比如下面給出的一個類,所有我們在設(shè)置hashmap的鍵值時需要特別注意),在hashmap的文檔里面有這么一段描述,每個哈希桶中元素數(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)計來看,hashmap的鍵值正常(不同對象的hash值不同的情況),哈希桶數(shù)量超過8個概率低于千萬分之一,所以我們通常認(rèn)為hashmap的查詢時間復(fù)雜度為O(1)

PS:

1、哈希沖突百分百的類

 /**
    測試哈希沖突的類,所有的對象都返回同樣的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、我們在實際使用hashmap時需要確保實現(xiàn)hashcode方法以及equals方法,否則不能作為hashmap的鍵值

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

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

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

HashMap底層采用了hash算法

根據(jù) key 獲得 hashCode 值

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

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

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

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

相關(guān)文章

  • 時間中間鍵的整理

    時間中間鍵的整理

    這篇文章主要介紹了時間中間鍵的整理的相關(guān)資料,如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • Spring觀察者模式之事件發(fā)布訂閱實現(xiàn)和源碼詳解

    Spring觀察者模式之事件發(fā)布訂閱實現(xiàn)和源碼詳解

    這篇文章主要介紹了Spring觀察者模式之事件發(fā)布訂閱實現(xiàn)和源碼詳解,Spring認(rèn)為發(fā)布訂閱主題,其實可以理解為事件驅(qū)動的編碼,先來實現(xiàn)以下Spring容器中的事件發(fā)布訂閱,需要的朋友可以參考下
    2024-01-01
  • Java面向?qū)ο蠡A(chǔ)知識之委托和lambda

    Java面向?qū)ο蠡A(chǔ)知識之委托和lambda

    這篇文章主要介紹了Java面向?qū)ο蟮闹泻?lambda,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-11-11
  • Java語言多線程終止中的守護(hù)線程實例

    Java語言多線程終止中的守護(hù)線程實例

    這篇文章主要介紹了Java語言多線程終止中的守護(hù)線程實例,具有一定借鑒價值,需要的朋友可以參考下
    2017-12-12
  • Java中常見的4種限流算法詳解

    Java中常見的4種限流算法詳解

    這篇文章主要介紹了Java中常見的4種限流算法詳解,FixedWindowRateLimiter 類表示一個固定窗口限流器,使用 limit 和 interval 參數(shù)分別表示限制請求數(shù)量和時間間隔,缺點是短時間內(nèi)可能會流量翻倍,需要的朋友可以參考下
    2023-12-12
  • Java多線程及分布式爬蟲架構(gòu)原理解析

    Java多線程及分布式爬蟲架構(gòu)原理解析

    這篇文章主要介紹了Java多線程及分布式爬蟲架構(gòu)原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • Ibatis配置xml文件CDATA使用方法詳解

    Ibatis配置xml文件CDATA使用方法詳解

    這篇文章主要介紹了Ibatis配置xml文件CDATA使用方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-12-12
  • Spring和SpringMVC父子容器關(guān)系初窺(小結(jié))

    Spring和SpringMVC父子容器關(guān)系初窺(小結(jié))

    這篇文章主要介紹了Spring和SpringMVC父子容器關(guān)系初窺(小結(jié)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • SpringBoot整合mybatis常見問題(小結(jié))

    SpringBoot整合mybatis常見問題(小結(jié))

    這篇文章主要介紹了SpringBoot整合mybatis常見問題(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java數(shù)據(jù)結(jié)構(gòu)之哈夫曼樹概述及實現(xiàn)

    Java數(shù)據(jù)結(jié)構(gòu)之哈夫曼樹概述及實現(xiàn)

    文中詳細(xì)講了關(guān)于Java哈夫曼樹的概述以及用Java實現(xiàn)的方法,對各位正在學(xué)習(xí)java數(shù)據(jù)結(jié)構(gòu)的小伙伴們有很大的幫助喲,需要的朋友可以參考下
    2021-05-05

最新評論