成人AV在线无码|婷婷五月激情色,|伊人加勒比二三四区|国产一区激情都市|亚洲AV无码电影|日av韩av无码|天堂在线亚洲Av|无码一区二区影院|成人无码毛片AV|超碰在线看中文字幕

hashcode是給哪些數(shù)據(jù)使用的 linkedset使用技巧?

linkedset使用技巧?從源碼的角度來對LinkedHashSet尋根問底!先一覽LinkedHashSet類中的所有方法,發(fā)現(xiàn)就是一些構(gòu)造方法,沒什么特別的。。spliterator方法也只是個

linkedset使用技巧?

從源碼的角度來對LinkedHashSet尋根問底!

先一覽LinkedHashSet類中的所有方法,發(fā)現(xiàn)就是一些構(gòu)造方法,沒什么特別的。。spliterator方法也只是個迭代器!

從構(gòu)造器中的super方法點過去可得見端倪,原來構(gòu)造器中的父級構(gòu)造器使用的是LinkedHashMap進行實例化,那么LinkedHashSet的特性勢必跟LinkedHashMap息息相關(guān),換句話說LinkedHashSet的輸出有序來自于LinkedHashMap;

下面對LinkedHashMap進行詳細(xì)分析:

LinkedHashMap繼承HashMap,實現(xiàn)了Map,很明顯LinkedHashMap也算是HashMap,還保存了數(shù)組 鏈表的結(jié)構(gòu),至于有序的原因肯定不會是因為Map接口和繼承HashMap,也就是說LinkedHashMap的有序,肯定就是在LinkedHashMap類中實現(xiàn)的;

HashMap的底層數(shù)據(jù)結(jié)構(gòu)是使用數(shù)組中的位置作為桶,每個桶中放置一份鏈表(或者紅黑樹),而hashCod

Sardine調(diào)用put方法的底層實現(xiàn)怎么做?

hashmap put方法的實現(xiàn):

12345678910111213141516171819 首先對key做null檢查。如果key是null,會被存儲到table[0],因為null的hash值總是0。

key的hashcode()方被調(diào)用,然后計算hash值。hash值用來找到存儲Entry對象的數(shù)組的索引。有時候hash函數(shù)可能寫的很不好,所以JDK的設(shè)計者添加了另一個叫做hash()的方法,它接收剛才計算的hash值作為參數(shù)。如果你想了解更多關(guān)于hash()函數(shù)的東西,可以參考:hashmap中的hash和indexFor方法

indexFor(hash,table.length)用來計算在table數(shù)組中存儲Entry對象的精確的索引。

在我們的例子中已經(jīng)看到,如果兩個key有相同的hash值(也叫),他們會以鏈表的形式來存儲。所以,這里我們就迭代鏈表。

· 如果在剛才計算出來的索引位置沒有元素,直接把Entry對象放在那個索引上。

· 如果索引上有元素,然后會進行迭代,一直到Entry-gtnext是null。當(dāng)前的Entry對象變成鏈表的下一個節(jié)點。

· 如果我們再次放入同樣的key會怎樣呢?邏輯上,它應(yīng)該替換老的value。事實上,它確實是這么做的。在迭代的過程中,會調(diào)用equals()方法來檢查key的相等性(key.equals(k)),如果這個方法返回true,它就會用當(dāng)前Entry的value來替換之前的value。

2.hashMap get方法的解析:

1234567 當(dāng)你傳遞一個key從hashmap總獲取value的時候:

對key進行null檢查。如果key是null,table[0]這個位置的元素將被返回。

key的hashcode()方法被調(diào)用,然后計算hash值。

indexFor(hash,table.length)用來計算要獲取的Entry對象在table數(shù)組中的精確的位置,使用剛才計算的hash值。

在獲取了table數(shù)組的索引之后,會迭代鏈表,調(diào)用equals()方法檢查key的相等性,如果equals()方法返回true,get方法返回Entry對象的value,否則,返回null。

3.要牢記以下關(guān)鍵點:

· HashMap有一個叫做Entry的內(nèi)部類,它用來存儲key-value對?!?上面的Entry對象是存儲在一個叫做table的Entry數(shù)組中。· table的索引在邏輯上叫做“桶”(bucket),它存儲了鏈表的第一個元素。· key的hashcode()方法用來找到Entry對象所在的桶?!?如果兩個key有相同的hash值,他們會被放在table數(shù)組的同一個桶里面?!?key的equals()方法用來確保key的唯一性?!?value對象的equals()和hashcode()方法根本一點用也沒有。簡單地說,HashMap 在底層將 key-value 當(dāng)成一個整體進行處理,這個整體就是一個 Entry 對象。HashMap 底層采用一個 Entry[] 數(shù)組來保存所有的 key-value 對,當(dāng)需要存儲一個 Entry 對象時,會根據(jù)hash算法來決定其在數(shù)組中的存儲位置,在根據(jù)equals方法決定其在該數(shù)組位置上的鏈表中的存儲位置;當(dāng)需要取出一個Entry時, 也會根據(jù)hash算法找到其在數(shù)組中的存儲位置,再根據(jù)equals方法從該位置上的鏈表中取出該Entry。

HashMap的resize(rehash)

當(dāng)hashmap中的元素越來越多的時候,碰撞的幾率也就越來越高(因為數(shù)組的長度是固定的),所以為了提高查詢的效率,就要對hashmap的數(shù)組進行擴容,數(shù)組擴容這個操作也會出現(xiàn)在ArrayList中,所以這是一個通用的操作,很多人對它的性能表示過懷疑,不過想想我們的“均攤”原理,就釋然了,而在hashmap數(shù)組擴容之后,最消耗性能的點就出現(xiàn)了:原數(shù)組中的數(shù)據(jù)必須重新計算其在新數(shù)組中的位置,并放進去,這就是resize。 那么hashmap什么時候進行擴容呢?當(dāng)hashmap中的元素個數(shù)超過數(shù)組大小*loadFactor時,就會進行數(shù)組擴容,loadFactor的默認(rèn)值為0.75,也就是說,默認(rèn)情況下,數(shù)組大小為16,那么當(dāng)hashmap中元素個數(shù)超過16*0.7512的時候,就把數(shù)組的大小擴展為2*1632,即擴大一倍,然后重新計算每個元素在數(shù)組中的位置,而這是一個非常消耗性能的操作,所以如果我們已經(jīng)預(yù)知hashmap中元素的個數(shù),那么預(yù)設(shè)元素的個數(shù)能夠有效的提高h(yuǎn)ashmap的性能。比如說,我們有1000個元素new HashMap(1000), 但是理論上來講new HashMap(1024)更合適,不過上面annegu已經(jīng)說過,即使是1000,hashmap也自動會將其設(shè)置為1024。 但是new HashMap(1024)還不是更合適的,因為0.75*1000 lt 1000, 也就是說為了讓0.75 * size gt 1000, 我們必須這樣new HashMap(2048)才最合適,既考慮了amp的問題,也避免了resize的問題。

標(biāo)簽: