欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中的TreeMap底層源碼分析

 更新時(shí)間:2023年12月15日 08:30:48   作者:愛喝咖啡的程序員  
這篇文章主要介紹了Java中的TreeMap底層源碼分析,TreeMap與Hashmap、LinkedHashMap不同,他的底層不再是數(shù)組,而是一顆紅黑樹,在插入、刪除或者替換元素時(shí),TreeMap能按照事先約定的順序來對(duì)key進(jìn)行排序和迭代查詢,需要的朋友可以參考下

一. 基本原理和優(yōu)缺點(diǎn)

TreeMap與Hashmap、LinkedHashMap不同,他的底層不再是數(shù)組,而是一顆紅黑樹。

在插入、刪除或者替換元素時(shí),TreeMap能按照事先約定的順序來對(duì)key進(jìn)行排序和迭代查詢。

支持二叉搜索,因此做查詢操作時(shí),時(shí)間復(fù)雜度是O(logn),雖然比起純粹使用數(shù)組要慢O(1),但是比普通的鏈表要快O(n)。

插入數(shù)據(jù)類似鏈表,只調(diào)整幾個(gè)指針就實(shí)現(xiàn)插入操作。

TreeMap的缺點(diǎn)在于,為了使用紅黑樹,每次新增、刪除、修改一個(gè)節(jié)點(diǎn)后,都需要重新調(diào)整整顆樹,達(dá)到紅黑樹的要求,這個(gè)調(diào)整的過程可能涉及到變色,也可能涉及到左旋、右旋,所以耗時(shí)??!

二. 源碼分析

2.1 put(K key, V value)

TreeMap<Integer, String> map = new TreeMap<>();
map.put(2, "張三");
map.put(1, "李四");
map.put(3, "王五");
map.put(4, "趙六");

Treemap默認(rèn)使用key的升序排序,如果遍歷上方的map,能獲取到1->2->3->4排列順序的key-value對(duì)。

我們也可以自定義比較key的方法,具體的做法如下:

Map<Integer, String> map = new TreeMap<Integer, String>(new Comparator<Integer> () {
	@Override
	public int compare(Integer o1, Integer o2) {
		return o2 - o1;
	}
}) {};

此時(shí),再次遍歷map,能獲取到4->3->2->1排列順序的key-value對(duì)。

我們可以把TreeMap put( )方法的源碼分解成幾個(gè)部分。

首先,判斷當(dāng)前TreeMap有沒有節(jié)點(diǎn),如果連一個(gè)節(jié)點(diǎn)都沒有,那好辦,就拿著本次待新增的k-v,做成一個(gè)節(jié)點(diǎn),此時(shí)紅黑樹只有一個(gè)節(jié)點(diǎn)。

Entry<K,V> t = root;
if (t == null) {
	compare(key, key); // type (and possibly null) check
	root = new Entry<>(key, value, null);
	size = 1;
	modCount++;
	return null;
}

接著,將待插入的key與根節(jié)點(diǎn)對(duì)應(yīng)的key進(jìn)行比較,這里就可以自定義比較方式了。

Comparator<? super K> cpr = comparator;
if (cpr != null) {
	do {
		parent = t;
		cmp = cpr.compare(key, t.key);
		if (cmp < 0)
			t = t.left;
		else if (cmp > 0)
			t = t.right;
		else
			return t.setValue(value);
	} while (t != null);
}
else {
	if (key == null)
		throw new NullPointerException();
	@SuppressWarnings("unchecked")
		Comparable<? super K> k = (Comparable<? super K>) key;
	do {
		parent = t;
		cmp = k.compareTo(t.key);
		if (cmp < 0)
			t = t.left;
		else if (cmp > 0)
			t = t.right;
		else
			return t.setValue(value);
	} while (t != null);
}

上圖中這么大一坨代碼,無非就是列舉了兩種情況,如果沒有顯示的給出Comparator,則使用key的compareTo()方法比較大小。如果給出了顯示的Comparator,則使用自定義的compare()方法進(jìn)行比較。

然后,把較小的節(jié)點(diǎn)掛到根節(jié)點(diǎn)的左邊,把較大的節(jié)點(diǎn)掛到根節(jié)點(diǎn)的右邊。這不就是二叉搜索樹的概念么。

if (cmp < 0)
	parent.left = e;
else
	parent.right = e;

最后,使用紅黑樹相關(guān)的算法,利用變色啊、旋轉(zhuǎn)啊等手段,使添加了節(jié)點(diǎn)的二叉搜索樹重新成為紅黑樹。

fixAfterInsertion(e);

2.2 紅黑樹節(jié)點(diǎn)的結(jié)構(gòu)

K key;
V value;
Entry<K,V> left;
Entry<K,V> right;
Entry<K,V> parent;
boolean color = BLACK;

到此這篇關(guān)于Java中的TreeMap底層源碼分析的文章就介紹到這了,更多相關(guān)TreeMap源碼分析內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis Mapper的xml文件中resultType值的使用說明

    mybatis Mapper的xml文件中resultType值的使用說明

    這篇文章主要介紹了mybatis Mapper的xml文件中resultType值的使用說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • java中堆內(nèi)存與棧內(nèi)存的知識(shí)點(diǎn)總結(jié)

    java中堆內(nèi)存與棧內(nèi)存的知識(shí)點(diǎn)總結(jié)

    在本篇文章里小編給大家整理的是關(guān)于java中堆內(nèi)存與棧內(nèi)存的知識(shí)點(diǎn)總結(jié),有需要的朋友們可以跟著學(xué)習(xí)下。
    2019-12-12
  • Java實(shí)現(xiàn)JDK動(dòng)態(tài)代理的原理詳解

    Java實(shí)現(xiàn)JDK動(dòng)態(tài)代理的原理詳解

    這篇文章主要介紹了Java實(shí)現(xiàn)JDK動(dòng)態(tài)代理的原理詳解,Java常用的動(dòng)態(tài)代理模式有JDK動(dòng)態(tài)代理,也有cglib動(dòng)態(tài)代理,本文重點(diǎn)講解JDK的動(dòng)態(tài)代理,需要的小伙伴可以參考一下的相關(guān)資料
    2022-07-07
  • SpringBoot+Shiro+LayUI權(quán)限管理系統(tǒng)項(xiàng)目源碼

    SpringBoot+Shiro+LayUI權(quán)限管理系統(tǒng)項(xiàng)目源碼

    本項(xiàng)目旨在打造一個(gè)基于RBAC架構(gòu)模式的通用的、并不復(fù)雜但易用的權(quán)限管理系統(tǒng),通過SpringBoot+Shiro+LayUI權(quán)限管理系統(tǒng)項(xiàng)目可以更好的幫助我們掌握springboot知識(shí)點(diǎn),感興趣的朋友一起看看吧
    2021-04-04
  • 基于springboot攔截器HandlerInterceptor的注入問題

    基于springboot攔截器HandlerInterceptor的注入問題

    這篇文章主要介紹了springboot攔截器HandlerInterceptor的注入問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringTask實(shí)現(xiàn)定時(shí)任務(wù)方法講解

    SpringTask實(shí)現(xiàn)定時(shí)任務(wù)方法講解

    通過重寫Schedu lingConfigurer方法實(shí)現(xiàn)對(duì)定時(shí)任務(wù)的操作,單次執(zhí)行、停止、啟動(dòng)三個(gè)主要的基本功能,動(dòng)態(tài)的從數(shù)據(jù)庫(kù)中獲取配置的定時(shí)任務(wù)cron信息,通過反射的方式靈活定位到具體的類與方法中
    2023-02-02
  • Java通過SSM完成水果商城批發(fā)平臺(tái)流程

    Java通過SSM完成水果商城批發(fā)平臺(tái)流程

    這是一個(gè)使用了java+SSM開發(fā)的網(wǎng)上水果商城批發(fā)平臺(tái),是一個(gè)實(shí)戰(zhàn)小練習(xí),具有水果商城批發(fā)該有的所有功能,感興趣的朋友快來看看吧
    2022-06-06
  • Java利用序列化實(shí)現(xiàn)對(duì)象深度clone的方法

    Java利用序列化實(shí)現(xiàn)對(duì)象深度clone的方法

    這篇文章主要介紹了Java利用序列化實(shí)現(xiàn)對(duì)象深度clone的方法,實(shí)例分析了java序列化及對(duì)象克隆的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • HttpClient實(shí)現(xiàn)文件上傳功能

    HttpClient實(shí)現(xiàn)文件上傳功能

    這篇文章主要為大家詳細(xì)介紹了利用HttpClient實(shí)現(xiàn)文件上傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • log4j.properties 配置(實(shí)例講解)

    log4j.properties 配置(實(shí)例講解)

    下面小編就為大家?guī)硪黄猯og4j.properties 配置(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08

最新評(píng)論