在了解 treemap 之前,我們來看看日常工作中排序的兩種方式,作為我們學習的基礎儲備,兩種方式的**如下:
@data
class
entry
implements
comparable
@override
public
intcompareto
(entry o)
}@test
public
void
execute()
collections.
sort
(list1)
; system.out.
println
("list1: "
+ json.
tojsonstring
(list1));
// 第二種排序,從大到小排序,利用外部排序器 comparator 進行排序
list
list2 =
newarraylist
<
>()
;for
(int i =
5; i >
0; i--
) collections.
sort
(list2,
newcomparator
()})
; system.out.
println
("list2: "
+ json.
tojsonstring
(list2));
}
執行結果:
list1: [,,,,]
list2: [,,,,]
以上兩種就是分別通過 comparable 和 comparator 兩者進行排序的方式,而 treemap 利用的也是此原理,從而實現了對 key 的排序。
treemap 底層的資料結構就是紅黑樹,和 hashmap 的紅黑樹結構一樣。
不同的是,treemap 可利用了紅黑樹左節點小,右節點大的效能,根據 key 進行排序,使每個元素都能夠插入到紅黑樹大小適當的位置,維護了 key 的大小關係,適用於 key 需要排序的場景。
因為底層使用的是平衡紅黑樹的結構,所以 containskey、get、put、remove 等方法的時間複雜度都是 log(n)。
treemap 常見的屬性有:
// 比較器。
// 如果外部有傳進來 comparator 比較器,則用外部的
// 如果外部比較器為空,則使用 key 自己實現的 comparable#comparetof 方法
private
final comparator<
?super k> comparator;
// 紅黑樹的根節點
private
transient entry
root;
// 紅黑樹已有元素大小
private
transient
int size =0;
// 樹結構變化的版本號
private
transient
int modcount =0;
// red-black mechanics
private
static
final
boolean red =
false
;private
static
final
boolean black =
true
;// 紅黑樹的節點
static
final
class
entry
implements
map.entry
}
treemap 新增節點原始碼:
public v put
(k key, v value)
int cmp;
entry
parent;
// split comparator and comparable paths
comparator<
?super k> cpr = comparator;
if(cpr != null)
while
(t != null);}
else
while
(t != null);}
// 到這一步時已經找到了當前要新增節點 key 的父節點 parent 了
entry
e =newentry
<
>
(key, value, parent)
;// cmp 代表最後一次對比的大小,小於 0,代表 e 在上乙個節點的左邊
if(cmp <0)
parent.left = e;
// cmp 代表左後一次對比的大小,大於 0,代表 e 在上乙個節點的右邊
else
parent.right = e;
// 相等的情況上面尋找 parent 時已經做過了
// 著色旋轉,達到平衡
fixafterinsertion
(e);
size++
; modcount++
;return null;
}
從原始碼中,我們可以看到:
新增節點時,就是利用了紅黑樹左小右大的特性,從根節點不斷往下查詢,直到找到節點是 null 為止,節點為 null 說明到達了葉子節點;
查詢的過程中,發現 key 值已經存在,直接覆蓋值;
treemap 是禁止 key 是 null 值的。
類似的,treemap 查詢也是類似的原理。
treemap 相對來說比較簡單,紅黑樹和 hashmap 比較類似,比較關鍵的是通過 compare 來比較 key 的大小,然後利用紅黑樹左小右大的特性,為每個 key 找到自己的位置,從而維護了 key 的大小排序順序。
------------------------------------- end -------------------------------------
TreeMap 原始碼分析
treemap底層是使用紅黑樹實現的儲存鍵值對的map容器,可以通過比較器進行排序。紅黑樹本質上是一棵弱平衡二叉樹,它的節點有紅色和黑色兩種顏色。主要特性有五點。1 每個節點或者是黑色,或者是紅色。2 根節點是黑色。3 每個葉子節點 nil 是黑色。注意 這裡葉子節點,是指為空 nil或null 的...
TreeMap原始碼分析
public v put k key,v value int cmp entryparent split comparator and comparable paths comparator cpr comparator if cpr null while t null else while t n...
TreeMap的原始碼
目錄 元素結構treemapentry 存放元素的邏輯 獲取元素 static final class treemapentryimplements map.entrypublic v put k key,v value int cmp treemapentryparent comparator c...