08 TreeMap 核心原始碼解析(集合)

2021-10-03 10:10:02 字數 3120 閱讀 8548

在了解 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...