广西十一选五玩法|广西十一选五开奖查询
  • HashMap和TreeMap的內部結構

    發布:51Code 時間: 2019-03-15 14:53

  • 一、HashMap 1、基于哈希表的 Map 接口的實現。此實現提供所有可選的映射操作,并允許使用 null 值和 null 鍵。(除了非同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。)此類不...

  • 一、HashMap 

    1、基于哈希表的 Map 接口的實現。此實現提供所有可選的映射操作,并允許使用 null 值和 null 鍵。(除了非同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。)此類不保證映射的順序,特別是它不保證該順序恒久不變。

    2、HashMap 的實例有兩個參數影響其性能:初始容量 和加載因子。容量是哈希表中桶的數量,初始容量只是哈希表在創建時的容量。加載因子是哈希表在其容量自動增加之前可以達到多滿的一種尺度。當哈希表中的條目數超出了加載因子與當前容量的乘積時,則要對該哈希表進行rehash 操作(即重建內部數據結構),從而哈希表將具有大約兩倍的桶數。

    按照key關鍵字的哈希值和buckets數組的長度取模查找桶的位置,如果key的哈希值相同,Hash沖突(也就是指向了同一個桶)則每次新添加的作為頭節點,而最先添加的在表尾。

    HashMap中的桶的個數就是下圖中的0- n的數組的長度,存儲第一個entry的位置叫‘桶(bucket)’而桶中只能存一個值也就是鏈表的頭節點,鏈表的每個節點就是添加的一個值(HashMap內部類Entry的實例Entry有哪些屬性之后在詳說),也可以這樣理解,一個entry 類型的存儲鏈表的數組。數組的索引位置就是一個個桶的索引地址。

    從上圖我們可以發現哈希表是由數組+鏈表組成的,一個長度為16的數組中,每個元素存儲的是一個鏈表的頭結點。那么這些元素是按照什么樣的規則存儲到數組中呢。一般情況是通過hash(key)%len獲得,也就是元素的key的哈希值對數組長度取模得到。比如上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12。所以12、28、108以及140都存儲在數組下標為12的位置。

    HashMap簡單總結:

    1、HashMap 是鏈式數組(存儲鏈表的數組)實現查詢速度可以,而且能快速的獲取key對應的value;

    2、查詢速度的影響因素有 容量和負載因子,容量大負載因子小查詢速度快但浪費空間,反之則相反;

    3、數組的index值是(key 關鍵字, hashcode為key的哈希值, len 數組的大小):hashcode%len的值來確定,如果容量大負載因子小則index相同(index相同也就是指向了同一個桶)的概率小,鏈表長度小則查詢速度快,反之index相同的概率大鏈表比較長查詢速度慢。

    4、對于HashMap以及其子類來說,他們是采用hash算法來決定集合中元素的存儲位置,當初始化HashMap的時候系統會創建一個長度為capacity的Entry數組,這個數組里可以存儲元素的位置稱為桶(bucket),每一個桶都有其指定索引,系統可以根據索引快速訪問該桶中存儲的元素。

    5、無論何時HashMap 中的每個桶都只存儲一個元素(Entry 對象)。由于Entry對象可以包含一個引用變量用于指向下一個Entry,因此可能出現HashMap 的桶(bucket)中只有一個Entry,但這個Entry指向另一個Entry 這樣就形成了一個Entry 鏈。

    6、通過上面的源碼發現HashMap在底層將key_value對當成一個整體進行處理(Entry 對象)這個整體就是一個Entry對象,當系統決定存儲HashMap中的key_value對時,完全沒有考慮Entry中的value,而僅僅是根據key的hash值來決定每個Entry的存儲位置。

    JDK1.8中使用一個Node數組來存儲數據,但這個Node可能是鏈表結構,也可能是紅黑樹結構如果插入的key的hashcode相同,那么這些key也會被定位到Node數組的同一個格子里。

    如果同一個格子里的key不超過8個,使用鏈表結構存儲。如果超過了8個,那么會調用treeifyBin函數,將鏈表轉換為紅黑樹。那么即使hashcode完全相同,由于紅黑樹的特點,查找某個特定元素,也只需要O(log n)的開銷

    也就是說put/get的操作的時間復雜度最差只有O(log n)。

    需要注意:key的對象,必須正確的實現了Compare接口

    二、TreeMap

    紅黑樹是一種近似平衡的二叉查找樹,它能夠確保任何一個節點的左右子樹的高度差不會超過二者中較低那個的一陪。具體來說,紅黑樹是滿足如下條件的二叉查找樹(binary search tree):

    1.每個節點要么是紅色,要么是黑色。

    2.根節點必須是黑色

    3.紅色節點不能連續(也即是,紅色節點的孩子和父親都不能是紅色)。

    4.對于每個節點,從該點至null(樹尾端)的任何路徑,都含有相同個數的黑色節點。

    在樹的結構發生改變時(插入或者刪除操作),往往會破壞上述條件3或條件4,需要通過調整使得查找樹重新滿足紅黑樹的條件。

    2、TreeMap的底層使用了紅黑樹來實現,像TreeMap對象中放入一個key-value 鍵值對時,就會生成一個Entry對象,這個對象就是紅黑樹的一個節點,其實這個和HashMap是一樣的,一個Entry對象作為一個節點,只是這些節點存放的方式不同。

    3、存放每一個Entry對象時都會按照key鍵的大小按照二叉樹的規范進行存放,所以TreeMap中的數據是按照key從小到大排序的。

    TreeMap總結:

    程序添加新節點時,總是從樹的根節點開始比較,即將根節點當成當前節點。如果新增節點大于當前節點并且當前節點的右節點存在,則以右節點作為當前節點,如果新增節點小于當前節點并且當前節點的左子節點存在,則以左子節點作為當前節點;如果新增節點等于當前節點,則用新增節點覆蓋當前節點,并結束循環 直到某個節點的左右子節點不存在,將新節點添加為該節點的子節點。如果新節點比該節點大,則添加其為右子節點。如果新節點比該節點小,則添加其為左子節點。

    文章來源:網絡 版權歸原作者所有
    如涉及知識產權問題,請權利人聯系博為峰小編(021-64471599-8103),我們將立即處理。

  • 上一篇:怎么理解分布式、高并發、多線程?

    下一篇:阿里巴巴的26款超神Java開源項目!建議收藏~

網站導航
Copyright(C)51Code軟件開發網 2003-2019 , 滬ICP備05003035號-6
广西十一选五玩法 龙虎对刷公式 苹果版 重庆时时彩 第1彩票网报彩票 重庆时时彩APP安卓系统 宝马后排娱乐 北京pk拾稳赚技巧公式 微信北京pk10计划 必中快三计划是真的吗 塞维利亚 快三大小单双计划软件下载