java8不是用紅黑樹來管理hashmap,而是在hash值相同的情況下(且重復(fù)數(shù)量大于8),用紅黑樹來管理數(shù)據(jù)。 紅黑樹相當(dāng)于排序數(shù)據(jù)??梢宰詣拥氖褂枚址ㄟM行定位。性能較高。
創(chuàng)新互聯(lián)是專業(yè)的崆峒網(wǎng)站建設(shè)公司,崆峒接單;提供網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè),網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進行崆峒網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
一般情況下,hash值做的比較好的話基本上用不到紅黑樹。
本文夾雜部分筆者個人觀點,如描述有誤,歡迎指正
寫這篇文章,是因為最近研究hashmap源碼的時候,會結(jié)合網(wǎng)上的一些博客來促進理解。而關(guān)于紅黑樹和鏈表相互轉(zhuǎn)換這一塊,大部分的文章都會這樣描述:hashmap中定義了兩個常量:
當(dāng)鏈表元素個數(shù)大于8的時候,就會轉(zhuǎn)換為紅黑樹;當(dāng)紅黑樹元素個數(shù)小于6的時候,就會轉(zhuǎn)換回鏈表。
筆者通過仔細(xì)觀察,發(fā)現(xiàn)這種說法并不嚴(yán)謹(jǐn)。hashMap中確實定義了這兩個常量,但并非簡單通過元素個數(shù)的判斷來進行轉(zhuǎn)換。
鏈表轉(zhuǎn)換為紅黑樹的最終目的,是為了解決在map中元素過多,hash沖突較大,而導(dǎo)致的讀寫效率降低的問題。在源碼的putVal方法中,有關(guān)紅黑樹結(jié)構(gòu)化的分支為:
即網(wǎng)上所說的,鏈表的長度大于8的時候,就轉(zhuǎn)換為紅黑樹,我們來看看treeifyBin方法:
可以看到在treeifyBin中并不是簡單地將鏈表轉(zhuǎn)換為紅黑樹,而是先判斷table的長度是否大于64,如果小于64,就通過擴容的方式來解決,避免紅黑樹結(jié)構(gòu)化。原因呢?筆者個人覺得鏈表長度大于8有兩種情況:
第二種情況是可以用擴容的方式來避免的,擴容后鏈表長度變短,讀寫效率自然提高。另外,擴容相對于轉(zhuǎn)換為紅黑樹的好處在于可以保證數(shù)據(jù)結(jié)構(gòu)更簡單。
由此可見并不是鏈表長度超過8就一定會轉(zhuǎn)換成紅黑樹,而是先嘗試擴容
基本思想是當(dāng)紅黑樹中的元素減少并小于一定數(shù)量時,會切換回鏈表。而元素減少有兩種情況:
hashMap的remove方法,會進入到removeNode方法,找到要刪除的節(jié)點,并判斷node類型是否為treeNode,然后進入刪除紅黑樹節(jié)點邏輯的removeTreeNode方法中,該方法有關(guān)解除紅黑樹結(jié)構(gòu)的分支如下:
可以看到,此處并沒有利用到網(wǎng)上所說的,當(dāng)節(jié)點數(shù)小于UNTREEIFY_THRESHOLD時才轉(zhuǎn)換,而是通過紅黑樹根節(jié)點及其子節(jié)點是否為空來判斷。而滿足該條件的最大紅黑樹結(jié)構(gòu)如下:
節(jié)點數(shù)為10,大于 UNTREEIFY_THRESHOLD(6),但是根據(jù)該方法的邏輯判斷,是需要轉(zhuǎn)換為鏈表的
resize的時候,判斷節(jié)點類型,如果是鏈表,則將鏈表拆分,如果是TreeNode,則執(zhí)行TreeNode的split方法分割紅黑樹,而split方法中將紅黑樹轉(zhuǎn)換為鏈表的分支如下:
這里才用到了 UNTREEIFY_THRESHOLD 的判斷,當(dāng)紅黑樹節(jié)點元素小于等于6時,才調(diào)用untreeify方法轉(zhuǎn)換回鏈表
在linux操作系統(tǒng)內(nèi)核實現(xiàn)里經(jīng)常使用的紅黑樹如下:
二叉樹,按中序遍歷后為一遞增數(shù)組,自平衡意味著樹的高度有一個上限,對于紅黑樹,其為2log(n+1),所以時間復(fù)雜度為最差為Olog(n)。
賦予二叉搜索樹自平衡特性的方法有多種,紅黑樹通過一下4條約束實現(xiàn)自平衡:
Every node is either red or black.
All NIL nodes (figure 1) are considered black.
A red node does not have a red child.
Every?path?from a given node to any of its descendant NIL nodes goes through the same number of black nodes.
其中根節(jié)點為黑色。
紅黑樹的搜索與二叉搜索樹無異,但是插入和刪除可能會違背上述四條原則。需要用到左旋右旋操作。左旋右旋上圖,可以看到左旋右旋本身不改變二叉搜索樹的特性,旋轉(zhuǎn)后必要時改變節(jié)點的顏色可消除插入或者刪除帶來的紅沖突和黑沖突,有時紅黑樹的重新平衡需要迭代進行。
紅黑樹比較適合的應(yīng)用場景:
需要動態(tài)插入、刪除、查找的場景,包括但不限于:
某些數(shù)據(jù)庫的增刪改查,比如select * from xxx where 這類條件檢索。
linux內(nèi)核中進程通過紅黑樹組織管理,便于快速插入、刪除、查找進程的task_struct。
linux內(nèi)存中內(nèi)存的管理:分配和回收。用紅黑樹組織已經(jīng)分配的內(nèi)存塊,當(dāng)應(yīng)用程序調(diào)用free釋放內(nèi)存的時候,可以根據(jù)內(nèi)存地址在紅黑樹中快速找到目標(biāo)內(nèi)存塊。
hashmap中(key,value)增、刪、改查的實現(xiàn);java 8就采用了RBTree替代鏈表。
Ext3文件系統(tǒng),通過紅黑樹組織目錄項。
參考資料的網(wǎng)頁上有比較的代碼,你可以仔細(xì)看下~~~
java中HashMap,LinkedHashMap,TreeMap,HashTable的區(qū)別
java為數(shù)據(jù)結(jié)構(gòu)中的映射定義了一個接口java.util.Map;它有四個實現(xiàn)類,分別是HashMap Hashtable LinkedHashMap 和TreeMap
Map主要用于存儲健值對,根據(jù)鍵得到值,因此不允許鍵重復(fù)(重復(fù)了覆蓋了),但允許值重復(fù)。
Hashmap 是一個最常用的Map,它根據(jù)鍵的HashCode 值存儲數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問速度,遍歷時,取得數(shù)據(jù)的順序是完全隨機的。HashMap最多只允許一條記錄的鍵為Null;允許多條記錄的值為 Null;HashMap不支持線程的同步,即任一時刻可以有多個線程同時寫HashMap;可能會導(dǎo)致數(shù)據(jù)的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。
Hashtable與 HashMap類似,它繼承自Dictionary類,不同的是:它不允許記錄的鍵或者值為空;它支持線程的同步,即任一時刻只有一個線程能寫Hashtable,因此也導(dǎo)致了 Hashtable在寫入時會比較慢。
LinkedHashMap保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時,先得到的記錄肯定是先插入的.也可以在構(gòu)造時用帶參數(shù),按照應(yīng)用次數(shù)排序。在遍歷的時候會比HashMap慢,不過有種情況例外,當(dāng)HashMap容量很大,實際數(shù)據(jù)較少時,遍歷起來可能會比LinkedHashMap慢,因為LinkedHashMap的遍歷速度只和實際數(shù)據(jù)有關(guān),和容量無關(guān),而HashMap的遍歷速度和他的容量有關(guān)。
TreeMap實現(xiàn)SortMap接口,能夠把它保存的記錄根據(jù)鍵排序,默認(rèn)是按鍵值的升序排序,也可以指定排序的比較器,當(dāng)用Iterator 遍歷TreeMap時,得到的記錄是排過序的。
一般情況下,我們用的最多的是HashMap,HashMap里面存入的鍵值對在取出的時候是隨機的,它根據(jù)鍵的HashCode值存儲數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問速度。在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。
TreeMap取出來的是排序后的鍵值對。但如果您要按自然順序或自定義順序遍歷鍵,那么TreeMap會更好。
LinkedHashMap 是HashMap的一個子類,如果需要輸出的順序和輸入的相同,那么用LinkedHashMap可以實現(xiàn),它還可以按讀取順序來排列,像連接池中可以應(yīng)用。
新聞名稱:紅黑樹java源代碼分析 jdk紅黑樹
文章起源:http://jinyejixie.com/article2/ddoghic.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、App開發(fā)、響應(yīng)式網(wǎng)站、企業(yè)建站、網(wǎng)站營銷、品牌網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)