hash系列集合的性能優化


 

hash系列的集合:

HashSet、LinkedHashSet     采用hash算法決定元素在集合中的存儲位置

HashMap、LinkedHashMap、Hashtable   采用hash算法決定key在集合中的存儲位置

 

 

hash表中可以存儲元素的位置,被稱為bucket(桶)。

在通常情況下,一個bucket里只存儲一個元素,此時性能最好,可根據hashCode直接定位元素所在的bucket,獲得元素。

但hash表的狀態是open的,在發生hash沖突時,一個bucket中會存儲多個元素,這些hash沖突的元素以鏈表形式存儲在一個bucket中:

此時hash表性能會下降,根據hash算法確定bucket位置后,還要遍歷鏈表,找到指定的元素。

如果我們重寫了自定義類的hashCode()、equals()則不會出現hash沖突的情況,一個bucket里只會存儲一個元素。

 

 

hash系列的集合都有以下屬性:

  • capacity     容量,hash表中bucket的數量
  • initial capacity     初始容量,創建hash表時bucket的數量
  • size    hash表中已裝元素的bucket數量
  • load factor  負載因子,等於size/capacity,即已裝元素的bucket數占總bucket數的比例。0表示空的hash表,0.5表示半滿的hash表。
  • 負載極限  0~1之間的一個float,表示當前hash表的最大填滿程度,即允許的load factor的最大值。

創建hash表時,此hash表的內存就確定了,根據hash算法確定的是元素在此hash表中的位置。

往hash表中添加元素時, 會先找到hash表中空的bucket,根據hash算法確定用哪個空的bucket來存儲元素。

 

load factor較小時,添加元素時很容易找到空的bucket,hash沖突少(因為可用的空bucket很多),存儲性能較高;已裝元素的bucket少,很容易從中找到指定的元素,查找性能較高;但遍歷集合(hash表)時,要過濾掉大量的空bucket,很花時間,所以遍歷時比較慢。

當load factor達到設置的負載極限時,會發生rehashing(重哈希/再散列),hash表會自動成倍地增加容量(capacity),將原有的元素都移到新的hash表中(會重新分配存儲位置),而此時原有的元素是極多的,這會增加很大的開銷。

負載極限設置較高時,節省內存(空桶較少),但添加、查找元素效率較低,時間開銷會增大;負載極限較低時,添加、查找元素效率較高,但會增加內存開銷。默認為0.75,是時間、空間的折中,我們可根據需要自行設置。

 

如果我們一開始就知道要存儲的元素個數,可以在創建hash表時就指定容量:元素總數/負載極限。這樣避免了rehashing,節省了時間開銷。且前中期hash表負載會很低,添加、查詢效率極高。

 

hash系列集合都有的3個重載構造函數:

()      //無形參,使用默認的capacity、負載極限(0.75)

(int capacity)     //指定容量

(int capacity,float 負載極限)    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM