欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

為什么HashMap加載因子一定是0.75而不是0.8,0.6

為什么HashMap加載因子一定是0.75而不是0.8,0.6,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

創(chuàng)新互聯(lián)公司專注于同安網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供同安營(yíng)銷型網(wǎng)站建設(shè),同安網(wǎng)站制作、同安網(wǎng)頁(yè)設(shè)計(jì)、同安網(wǎng)站官網(wǎng)定制、小程序定制開(kāi)發(fā)服務(wù),打造同安網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供同安網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。

為什么HashMap需要加載因子?

HashMap的底層是哈希表,是存儲(chǔ)鍵值對(duì)的結(jié)構(gòu)類型,它需要通過(guò)一定的計(jì)算才可以確定數(shù)據(jù)在哈希表中的存儲(chǔ)位置:

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}// AbstractMappublic int hashCode() {
     int h = 0;
     Iterator<Entry<K,V>> i = entrySet().iterator();
     while (i.hasNext())
         h += i.next().hashCode();

     return h;
}

一般的數(shù)據(jù)結(jié)構(gòu),不是查詢快就是插入快,HashMap就是一個(gè)插入慢、查詢快的數(shù)據(jù)結(jié)構(gòu)。

但這種數(shù)據(jù)結(jié)構(gòu)容易產(chǎn)生兩種問(wèn)題:① 如果空間利用率高,那么經(jīng)過(guò)的哈希算法計(jì)算存儲(chǔ)位置的時(shí)候,會(huì)發(fā)現(xiàn)很多存儲(chǔ)位置已經(jīng)有數(shù)據(jù)了(哈希沖突);② 如果為了避免發(fā)生哈希沖突,增大數(shù)組容量,就會(huì)導(dǎo)致空間利用率不高。

而加載因子就是表示Hash表中元素的填滿程度。

加載因子 = 填入表中的元素個(gè)數(shù) / 散列表的長(zhǎng)度

加載因子越大,填滿的元素越多,空間利用率越高,但發(fā)生沖突的機(jī)會(huì)變大了;

加載因子越小,填滿的元素越少,沖突發(fā)生的機(jī)會(huì)減小,但空間浪費(fèi)了更多了,而且還會(huì)提高擴(kuò)容rehash操作的次數(shù)。

沖突的機(jī)會(huì)越大,說(shuō)明需要查找的數(shù)據(jù)還需要通過(guò)另一個(gè)途徑查找,這樣查找的成本就越高。因此,必須在“沖突的機(jī)會(huì)”與“空間利用率”之間,尋找一種平衡與折衷。

所以我們也能知道,影響查找效率的因素主要有這幾種:

  • 散列函數(shù)是否可以將哈希表中的數(shù)據(jù)均勻地散列?

  • 怎么處理沖突?

  • 哈希表的加載因子怎么選擇?

本文主要對(duì)后兩個(gè)問(wèn)題進(jìn)行介紹。

解決沖突有什么方法?

1. 開(kāi)放定址法
Hi = (H(key) + di) MOD m,其中i=1,2,…,k(k<=m-1)

H(key)為哈希函數(shù),m為哈希表表長(zhǎng),di為增量序列,i為已發(fā)生沖突的次數(shù)。其中,開(kāi)放定址法根據(jù)步長(zhǎng)不同可以分為3種:

1.1 線性探查法(Linear Probing):di = 1,2,3,…,m-1

簡(jiǎn)單地說(shuō),就是以當(dāng)前沖突位置為起點(diǎn),步長(zhǎng)為1循環(huán)查找,直到找到一個(gè)空的位置,如果循環(huán)完了都占不到位置,就說(shuō)明容器已經(jīng)滿了。舉個(gè)栗子,就像你在飯點(diǎn)去街上吃飯,挨家去看是否有位置一樣。

1.2 平方探測(cè)法(Quadratic Probing):di = ±12, ±22,±32,…,±k2(k≤m/2)

相對(duì)于線性探查法,這就相當(dāng)于的步長(zhǎng)為di = i2來(lái)循環(huán)查找,直到找到空的位置。以上面那個(gè)例子來(lái)看,現(xiàn)在你不是挨家去看有沒(méi)有位置了,而是拿手機(jī)算去第i2家店,然后去問(wèn)這家店有沒(méi)有位置。

1.3 偽隨機(jī)探測(cè)法:di = 偽隨機(jī)數(shù)序列

這個(gè)就是取隨機(jī)數(shù)來(lái)作為步長(zhǎng)。還是用上面的例子,這次就是完全按心情去選一家店問(wèn)有沒(méi)有位置了。

但開(kāi)放定址法有這些缺點(diǎn):

  • 這種方法建立起來(lái)的哈希表,當(dāng)沖突多的時(shí)候數(shù)據(jù)容易堆集在一起,這時(shí)候?qū)Σ檎也挥押茫?/p>

  • 刪除結(jié)點(diǎn)的時(shí)候不能簡(jiǎn)單將結(jié)點(diǎn)的空間置空,否則將截?cái)嘣谒钊肷⒘斜碇蟮耐x詞結(jié)點(diǎn)查找路徑。因此如果要?jiǎng)h除結(jié)點(diǎn),只能在被刪結(jié)點(diǎn)上添加刪除標(biāo)記,而不能真正刪除結(jié)點(diǎn);

  • 如果哈希表的空間已經(jīng)滿了,還需要建立一個(gè)溢出表,來(lái)存入多出來(lái)的元素。

2. 再哈希法

Hi = RHi(key), 其中i=1,2,…,k

RHi()函數(shù)是不同于H()的哈希函數(shù),用于同義詞發(fā)生地址沖突時(shí),計(jì)算出另一個(gè)哈希函數(shù)地址,直到不發(fā)生沖突位置。這種方法不容易產(chǎn)生堆集,但是會(huì)增加計(jì)算時(shí)間。

所以再哈希法的缺點(diǎn)是:增加了計(jì)算時(shí)間。

3. 建立一個(gè)公共溢出區(qū)

假設(shè)哈希函數(shù)的值域?yàn)閇0, m-1],設(shè)向量HashTable[0,…,m-1]為基本表,每個(gè)分量存放一個(gè)記錄,另外還設(shè)置了向量OverTable[0,…,v]為溢出表?;颈碇写鎯?chǔ)的是關(guān)鍵字的記錄,一旦發(fā)生沖突,不管他們哈希函數(shù)得到的哈希地址是什么,都填入溢出表。

但這個(gè)方法的缺點(diǎn)在于:查找沖突數(shù)據(jù)的時(shí)候,需要遍歷溢出表才能得到數(shù)據(jù)。

4. 鏈地址法(拉鏈法)

將沖突位置的元素構(gòu)造成鏈表。在添加數(shù)據(jù)的時(shí)候,如果哈希地址與哈希表上的元素沖突,就放在這個(gè)位置的鏈表上。

拉鏈法的優(yōu)點(diǎn):

  • 處理沖突的方式簡(jiǎn)單,且無(wú)堆集現(xiàn)象,非同義詞絕不會(huì)發(fā)生沖突,因此平均查找長(zhǎng)度較短;

  • 由于拉鏈法中各鏈表上的結(jié)點(diǎn)空間是動(dòng)態(tài)申請(qǐng)的,所以它更適合造表前無(wú)法確定表長(zhǎng)的情況;

  • 刪除結(jié)點(diǎn)操作易于實(shí)現(xiàn),只要簡(jiǎn)單地刪除鏈表上的相應(yīng)的結(jié)點(diǎn)即可。

拉鏈法的缺點(diǎn):需要額外的存儲(chǔ)空間。

從HashMap的底層結(jié)構(gòu)中我們可以看到,HashMap采用是數(shù)組+鏈表/紅黑樹(shù)的組合來(lái)作為底層結(jié)構(gòu),也就是開(kāi)放地址法+鏈地址法的方式來(lái)實(shí)現(xiàn)HashMap。

為什么HashMap加載因子一定是0.75而不是0.8,0.6

為什么HashMap加載因子一定是0.75?而不是0.8,0.6?

從上文我們知道,HashMap的底層其實(shí)也是哈希表(散列表),而解決沖突的方式是鏈地址法。HashMap的初始容量大小默認(rèn)是16,為了減少?zèng)_突發(fā)生的概率,當(dāng)HashMap的數(shù)組長(zhǎng)度到達(dá)一個(gè)臨界值的時(shí)候,就會(huì)觸發(fā)擴(kuò)容,把所有元素rehash之后再放在擴(kuò)容后的容器中,這是一個(gè)相當(dāng)耗時(shí)的操作。

而這個(gè)臨界值就是由加載因子和當(dāng)前容器的容量大小來(lái)確定的:

臨界值 = DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR

即默認(rèn)情況下是16x0.75=12時(shí),就會(huì)觸發(fā)擴(kuò)容操作。

那么為什么選擇了0.75作為HashMap的加載因子呢?這個(gè)跟一個(gè)統(tǒng)計(jì)學(xué)里很重要的原理——泊松分布有關(guān)。

泊松分布是統(tǒng)計(jì)學(xué)和概率學(xué)常見(jiàn)的離散概率分布,適用于描述單位時(shí)間內(nèi)隨機(jī)事件發(fā)生的次數(shù)的概率分布。有興趣的讀者可以看看維基百科或者阮一峰老師的這篇文章:泊松分布和指數(shù)分布:10分鐘教程[1]

為什么HashMap加載因子一定是0.75而不是0.8,0.6

等號(hào)的左邊,P 表示概率,N表示某種函數(shù)關(guān)系,t 表示時(shí)間,n 表示數(shù)量。等號(hào)的右邊,λ 表示事件的頻率。

在HashMap的源碼中有這么一段注釋:

* Ideally, under random hashCodes, the frequency of
* nodes in bins follows a Poisson distribution
* (http://en.wikipedia.org/wiki/Poisson_distribution) with a
* parameter of about 0.5 on average for the default resizing
* threshold of 0.75, although with a large variance because of
* resizing granularity. Ignoring variance, the expected
* occurrences of list size k are (exp(-0.5) * pow(0.5, k) /
* factorial(k)). The first values are:
* 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
* more: less than 1 in ten million

在理想情況下,使用隨機(jī)哈希碼,在擴(kuò)容閾值(加載因子)為0.75的情況下,節(jié)點(diǎn)出現(xiàn)在頻率在Hash桶(表)中遵循參數(shù)平均為0.5的泊松分布。忽略方差,即X = λt,P(λt = k),其中λt = 0.5的情況,按公式:

為什么HashMap加載因子一定是0.75而不是0.8,0.6

計(jì)算結(jié)果如上述的列表所示,當(dāng)一個(gè)bin中的鏈表長(zhǎng)度達(dá)到8個(gè)元素的時(shí)候,概率為0.00000006,幾乎是一個(gè)不可能事件。

所以我們可以知道,其實(shí)常數(shù)0.5是作為參數(shù)代入泊松分布來(lái)計(jì)算的,而加載因子0.75是作為一個(gè)條件,當(dāng)HashMap長(zhǎng)度為length/size ≥ 0.75時(shí)就擴(kuò)容,在這個(gè)條件下,沖突后的拉鏈長(zhǎng)度和概率結(jié)果為:

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

那么為什么不可以是0.8或者0.6呢?

HashMap中除了哈希算法之外,有兩個(gè)參數(shù)影響了性能:初始容量和加載因子。初始容量是哈希表在創(chuàng)建時(shí)的容量,加載因子是哈希表在其容量自動(dòng)擴(kuò)容之前可以達(dá)到多滿的一種度量。

在維基百科來(lái)描述加載因子:

對(duì)于開(kāi)放定址法,加載因子是特別重要因素,應(yīng)嚴(yán)格限制在0.7-0.8以下。超過(guò)0.8,查表時(shí)的CPU緩存不命中(cache missing)按照指數(shù)曲線上升。因此,一些采用開(kāi)放定址法的hash庫(kù),如Java的系統(tǒng)庫(kù)限制了加載因子為0.75,超過(guò)此值將resize散列表。

在設(shè)置初始容量時(shí)應(yīng)該考慮到映射中所需的條目數(shù)及其加載因子,以便最大限度地減少擴(kuò)容rehash操作次數(shù),所以,一般在使用HashMap時(shí)建議根據(jù)預(yù)估值設(shè)置初始容量,以便減少擴(kuò)容操作。

選擇0.75作為默認(rèn)的加載因子,完全是時(shí)間和空間成本上尋求的一種折衷選擇。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。

網(wǎng)頁(yè)名稱:為什么HashMap加載因子一定是0.75而不是0.8,0.6
轉(zhuǎn)載源于:http://aaarwkj.com/article48/jpoohp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)微信公眾號(hào)、網(wǎng)站設(shè)計(jì)公司、關(guān)鍵詞優(yōu)化、網(wǎng)站策劃、品牌網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)
国产欧美日韩精品av| 密臀av一区二区三区| 又黄又爽区一区二区三| 欧美日韩亚洲精品一区二区三区 | 91亚洲精品一区二区三区| 91麻豆精品国产自产| 国产成人综合亚洲一区| av资源在线观看少妇丰满| 青青草日韩欧美在线观看| 大陆av剧情网站在线观看| 日本一区二区 视频| 国产一级二级三级久久| 91色老久久精品偷偷鲁无毒| 欧美日韩一区二区三区四区高清视频| 日韩亚洲欧美不卡在线| 欧美专区另类综合日韩| 国产手机在线91精品观看| 全部网站免费在线观看等| 97久久精品人妻一区二区三区| 无套内射精品一区二区| 亚洲另类欧美日韩中文字幕| 亚洲一区二区三区欧美精品| 午夜性色福利视频你懂的| 精品在欧美一区二区少妇| 亚洲精品一区久久狠狠欧美| 日韩中字伦理熟妇人妻| 国产精品重口调教系列| 亚洲精品成人久久国产| 日韩av手机在线不卡| 一区二区三区日韩国产电影| 亚洲男人天堂在线视频| 天堂av在线网址观看| 国产97精品在线播放| 亚洲国产成在人网站天堂| 91麻豆精品国产91久| 在线观看中文字幕有码| 久久精品国产亚洲av高清观看| 九九在线视频精品免费播放| 日日夜夜精品天天综合| 日韩在线啊啊啊的视频| 成人福利网站午夜一区|