Java Collections Framework 源碼分析(4.2 - TreeSet)

上一篇文章中介紹了 Set 接口和它的兩個主要實(shí)現(xiàn),HashSetLinkedHashSet。回憶一下它們的特點(diǎn)狂男,HashSet 特點(diǎn)是無序,而 LinkedHashSet 則是有有序的品腹,它的順序是按照集合內(nèi)元素的添加順序岖食。

它們具體的內(nèi)部實(shí)現(xiàn)也較為簡單,都是對兩個 Map 數(shù)據(jù)結(jié)構(gòu)的封裝舞吭,應(yīng)該都不難理解泡垃。

今天介紹的數(shù)據(jù)結(jié)構(gòu)也同屬于 Set 接口之下,同樣不能存放相同的元素羡鸥,但是最大的不同之處在于它是有順序的蔑穴,它就是 TreeSet

SortedSet

在開始分析源碼之前還是先來看看 TreeSet 的類圖:

TreeSet.png

從類圖上看惧浴,出現(xiàn)了兩個之前沒有見過的接口存和,即 SortedSetNavigableSet 。讓我們先來看看 SortedSet 的注釋和源碼。

注釋給我們提供了以下的這些信息:

  • SortedSet 是一個「有序」的集合捐腿,它的順序由 Comparable 或是 Comparator 的結(jié)果決定纵朋。這意味著 SortedSet 容器內(nèi)的元素必須實(shí)現(xiàn)這兩個接口中的任一一個。
  • 所有實(shí)現(xiàn) SortedSet 接口的具體類茄袖,需要提供 4 個不同的構(gòu)造函數(shù)操软,這里不再贅述,有興趣的讀者可以直接看這部分的注釋绞佩。
  • SortedSet 提供的部分獲取某個范圍元素的方法寺鸥,都是前閉后開的。如果需要兩個都是閉區(qū)間或是開區(qū)間品山,只能通過自己調(diào)整輸入?yún)?shù)來控制。

現(xiàn)在我們已經(jīng)了解了 SortedSetTreeSet 「有順序」的意思了烤低,接著就看看 SortedSet 接口上有哪些有意思的方法肘交。

  • first, last 方法分別是返回集合內(nèi)第一個和最后一個元素。
  • headSet(E toElement) 返回集合內(nèi)所有小于 toElement 元素的集合扑馁,注意這里是開區(qū)間涯呻,是「小于」而不是「小于等于」。
  • tailSet(E fromElement)headSet 類似腻要,返回所有大于等于 fromElement 元素的集合复罐,注意這里是閉區(qū)間,即是「大于等于」雄家。
  • subSet(E fromElement, E toElement) 返回 fromElementtoElement 范圍之間的元素集合效诅,注意這里是前面提到的前閉后開區(qū)間,即「大于等于」fromElement趟济,「小于」toElement 元素的集合乱投。

SortedSet 關(guān)鍵方法就這些,準(zhǔn)備進(jìn)入下一個接口 NavigableSet 吧顷编。

NavigableSet

NavigableSet 繼承了 SortedSet 接口戚炫,并增加了數(shù)個方法,讓我們逐一分析媳纬。

新增了 lower(E e)双肤,floor(E e)ceiling(E e)钮惠,higher(E e) 四個方法茅糜,分別返回集合內(nèi)「小于」,「小于等于」萌腿,「大于等于」限匣,「大于」輸入?yún)?shù)的 e 的元素,如果集合內(nèi)沒有符合條件的參數(shù),則返回 null米死。

pollFirst()pollLast() 分別返回并移除集合中最小和最大的元素锌历。

重載了父接口 SortedSet 中的 headSettailSet峦筒,subSet 這些方法究西,增加了額外的參數(shù),控制區(qū)間的閉合物喷,讓方法更加方便使用卤材,具體可以看對應(yīng)的方法簽名和注釋。

剩下值得一提的是 descendingSet 方法峦失,該方法會返回一個當(dāng)前集合降序排列的視圖扇丛,而注釋中也提及通常情況下升序操作的性能好于降序。

TreeSet

其實(shí)寫到這里 TreeSet 本身并沒有太多值得分析的尉辑,因?yàn)樗c HashSet 一樣帆精,真正存儲數(shù)據(jù),并進(jìn)行各種操作的是代理給了 TreeMap隧魄∽苛罚基本上前面提到的所有方法都是直接掉用了 TreeMap 上的相關(guān)方法」鹤模看下面的代碼片段:

private transient NavigableMap<E,Object> m;

public E last() {
    return m.lastKey();
}

public E pollFirst() {
    Map.Entry<E,?> e = m.pollFirstEntry();
    return (e == null) ? null : e.getKey();
}

public NavigableSet<E> headSet(E toElement, boolean inclusive) {
    return new TreeSet<>(m.headMap(toElement, inclusive));
}

額外可以從注釋中了解的就是 add襟企,removecontains 這幾個方法的時間復(fù)雜度為 log(n)狮含。

下階段預(yù)告

看完 Set 部分的源碼你會發(fā)現(xiàn)其實(shí)大部分?jǐn)?shù)據(jù)結(jié)構(gòu)的操作都是由 Map 這個數(shù)據(jù)結(jié)構(gòu)完成顽悼,包括了 HashMapTreeMap,而 Map 作為開發(fā)人員日常使用頻率最高的數(shù)據(jù)結(jié)構(gòu)之一辉川,可謂是 Java Collections Framework 中最核心的數(shù)據(jù)結(jié)構(gòu)之一表蝙,而它的代碼中也包含了大量必備的數(shù)據(jù)結(jié)構(gòu)知識和算法,在面試中也是被問到最多的乓旗。

很多讀者問我什么時候會開始 Map 源碼的講解府蛇,答案就是現(xiàn)在。從下一篇開始我會開始分析 Map 源碼屿愚,因?yàn)槠渲猩婕暗闹R點(diǎn)很多汇跨,我會寫的非常細(xì),估計(jì)會有4 ~ 5 篇專門來分析 Map 系列的源碼妆距。如果你希望真正了解和掌握 Java Collections Framework 的一些知識穷遂,我想接下來的文章是不容錯過的。我也歡迎你提出任何問題娱据,我都會回復(fù)你蚪黑。下一篇見!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市忌穿,隨后出現(xiàn)的幾起案子抒寂,更是在濱河造成了極大的恐慌,老刑警劉巖掠剑,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屈芜,死亡現(xiàn)場離奇詭異,居然都是意外死亡朴译,警方通過查閱死者的電腦和手機(jī)井佑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眠寿,“玉大人躬翁,你說我怎么就攤上這事《⒐埃” “怎么了姆另?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長坟乾。 經(jīng)常有香客問我,道長蝶防,這世上最難降的妖魔是什么甚侣? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮间学,結(jié)果婚禮上殷费,老公的妹妹穿的比我還像新娘。我一直安慰自己低葫,他們只是感情好详羡,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嘿悬,像睡著了一般实柠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上善涨,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天窒盐,我揣著相機(jī)與錄音,去河邊找鬼钢拧。 笑死蟹漓,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的源内。 我是一名探鬼主播葡粒,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嗽交?” 一聲冷哼從身側(cè)響起卿嘲,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎轮纫,沒想到半個月后腔寡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡掌唾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年放前,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片糯彬。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡凭语,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出撩扒,到底是詐尸還是另有隱情似扔,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布搓谆,位于F島的核電站炒辉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏泉手。R本人自食惡果不足惜黔寇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望斩萌。 院中可真熱鬧缝裤,春花似錦、人聲如沸颊郎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姆吭。三九已至榛做,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間猾编,已是汗流浹背瘤睹。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留答倡,地道東北人轰传。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像瘪撇,于是被迫代替她去往敵國和親获茬。 傳聞我的和親對象是個殘疾皇子港庄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一鹏氧、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對于byte類型而言...
    龍貓小爺閱讀 4,265評論 0 16
  • Java集合類可用于存儲數(shù)量不等的對象,并可以實(shí)現(xiàn)常用的數(shù)據(jù)結(jié)構(gòu)如棧,隊(duì)列等,Java集合還可以用于保存具有映射關(guān)...
    小徐andorid閱讀 1,942評論 0 13
  • 四、集合框架 1:String類:字符串(重點(diǎn)) (1)多個字符組成的一個序列佩谣,叫字符串把还。生活中很多數(shù)據(jù)的描述都采...
    佘大將軍閱讀 756評論 0 2
  • 概述 Java集合框架由Java類庫的一系列接口、抽象類以及具體實(shí)現(xiàn)類組成茸俭。我們這里所說的集合就是把一組對象組織到...
    absfree閱讀 1,254評論 0 10
  • Java集合框架 Java平臺提供了一個全新的集合框架吊履。“集合框架”主要由一組用來操作對象的接口組成调鬓。不同接口描述...
    小石38閱讀 360評論 0 0