集合13-TreeMap使用場(chǎng)景簡(jiǎn)析

0- 繼承結(jié)構(gòu)

1- 簡(jiǎn)介

  • TreeMap的底層實(shí)現(xiàn)原理

基于紅黑樹(shù)實(shí)現(xiàn)的排序Map

  • TreeMap增刪改查的時(shí)間復(fù)雜度

TreeMap的增刪改查和統(tǒng)計(jì)相關(guān)的操作的時(shí)間復(fù)雜度都為 O(logn)

  • TreeMap的key和value的要求
  1. 由于實(shí)現(xiàn)了Map接口,則key的值不允許重復(fù)(重復(fù)則覆蓋)丧慈,也不允許為null扫茅,按照key的自然順序排序或者Comparator接口指定的排序方法進(jìn)行排序。
  1. value允許重復(fù),也允許為null硅卢,當(dāng)key重復(fù)時(shí)低飒,會(huì)覆蓋此value值。

2- TreeMap的使用場(chǎng)景

考慮如下場(chǎng)景:

  • 需要基于排序的統(tǒng)計(jì)功能:

由于TreeMap是基于紅黑樹(shù)的實(shí)現(xiàn)的排序Map桑驱,對(duì)于增刪改查以及統(tǒng)計(jì)的時(shí)間復(fù)雜度都控制在O(logn)的級(jí)別上竭恬,相對(duì)于HashMap和LikedHashMap的統(tǒng)計(jì)操作的(最大的key跛蛋,最小的key,大于某一個(gè)key的所有Entry等等)時(shí)間復(fù)雜度O(n)具有較高時(shí)間效率痊硕。

  • 需要快速增刪改查的存儲(chǔ)功能:

相對(duì)于HashMap和LikedHashMap 這些 hash表的時(shí)間復(fù)雜度O(1)(不考慮沖突情況)赊级,TreeMap的增刪改查的時(shí)間復(fù)雜度為O(logn)就顯得效率較低。

  • 需要快速增刪改查而且需要保證遍歷和插入順序一致的存儲(chǔ)功能:

相對(duì)于HashMap和LikedHashMap 這些 hash表的時(shí)間復(fù)雜度O(1)(不考慮沖突情況)寿桨,TreeMap的增刪改查的時(shí)間復(fù)雜度為O(logn)就顯得效率較低此衅。但是HashMap并不保證任何順序性。LikedHashMap額外保證了Map的遍歷順序與put順序一致的有序性亭螟。

綜上:場(chǎng)景1適合使用TreeMap挡鞍,場(chǎng)景2適合使用HashMap,場(chǎng)景3適合使用LikedHashMap预烙,需要注意它們都是非線(xiàn)程安全的墨微,當(dāng)在并發(fā)場(chǎng)景下可以使用其他并發(fā)集合或者調(diào)用者在調(diào)用層去控制并發(fā)使得操作串行執(zhí)行。

3- TreeMap的方法列表


http://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html

4- 按照Value進(jìn)行排序

import java.util.*;
/**
 * @author zhanglbjames@163.com
 * @version Created on 2017/6/9.
 */
public class TestTreeMap {
    public static void main(String[] args){
        // 創(chuàng)建hashmap
        HashMap<Integer,Integer> hashMap = new HashMap<>();
        hashMap.put(1,5);
        hashMap.put(2,4);
        hashMap.put(3,3);
        hashMap.put(4,2);
        hashMap.put(5,1);
        hashMap.put(7,1);

        // 創(chuàng)建Value比較器
        ValueComparator valueComparator = new ValueComparator(hashMap);
        // 創(chuàng)建TreeMap
        TreeMap<Integer,Integer> treeMap = new TreeMap<>(valueComparator);
        //TreeMap<Integer,Integer> treeMap = new TreeMap<>();

        // 將HashMap中所有數(shù)據(jù)放入 TreeMap中
        //treeMap.putAll(hashMap);
        // 為了觀察每次變化扁掸,進(jìn)行分開(kāi)put

        System.out.println("--------------------- put into TreeMap --------------------");
        System.out.println(treeMap.put(1,5));
        System.out.println(treeMap.put(2,4));
        System.out.println(treeMap.put(3,3));
        System.out.println(treeMap.put(4,2));
        System.out.println(treeMap.put(5,1));
        System.out.println(treeMap.put(7,1));

        System.out.println("---------------------- sort result -------------------------");
        // 迭代TreeMap的結(jié)果
        Iterator<Map.Entry<Integer,Integer>> iterator = treeMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<Integer,Integer> entry = iterator.next();
            System.out.println("key : "+entry.getKey()+" value : " + entry.getValue());
        }
        System.out.println("after sorted, the size : " +treeMap.size());
    }
}

class ValueComparator implements Comparator<Integer> {

    // 一定要持有能根據(jù)Key的值找到對(duì)應(yīng)Value值的Map翘县,只有這樣才能在compare方法中比較key對(duì)應(yīng)的value
    // 默認(rèn)傳入的比較器都是針對(duì)key的比較器,如果想修改為Value的比較器需要通過(guò)持有k-v的Map
    private Map<Integer,Integer> map;

    public ValueComparator(Map map) {
        this.map = map;
    }
    @Override
    public int compare(Integer o1, Integer o2) {

        if (map.get(o1) > map.get(o2)){
            return 1;
        }else if(map.get(o1) < map.get(o2)){
            return -1;
        }
        // 如果比較value谴分,相同的value的Key將會(huì)發(fā)生合并锈麸,即Value的值是不允許重復(fù)的
        // 必須返回 0,否則get方法將返回null
        else return 0;
    }
}

輸出結(jié)果:

--------------------- put into TreeMap --------------------
null
null
null
null
null
1
---------------------- sort result -------------------------
key : 5 value : 1
key : 4 value : 2
key : 3 value : 3
key : 2 value : 4
key : 1 value : 5
after sorted, the size : 5
說(shuō)明:
  1. TreeMap默認(rèn)是根據(jù)Key來(lái)比較來(lái)排序的

  2. TreeMap的構(gòu)造方法允許使用指定的比較器來(lái)比較

  3. 可以實(shí)現(xiàn)通過(guò)比較Value來(lái)排序牺蹄,通過(guò)指定比較器來(lái)實(shí)現(xiàn)忘伞,注意比較器的compare方法接收的兩個(gè)參數(shù)都是Key,必須通過(guò)Key來(lái)獲取對(duì)應(yīng)的Value來(lái)比較
    才能實(shí)現(xiàn)按照Value來(lái)排序沙兰,否則還是按照key來(lái)排序的氓奈。

  4. TreeMap底層是紅黑樹(shù)來(lái)實(shí)現(xiàn)的,紅黑樹(shù)不允許重復(fù)的比較關(guān)鍵字鼎天, 所以如果比較器(如果沒(méi)有指定比較器舀奶,則默認(rèn)使用Key的自然順序或者Key實(shí)現(xiàn)的比較接口方法來(lái)比較)的比較結(jié)果為0,即比較關(guān)鍵字相等斋射,則將會(huì)發(fā)生覆蓋value育勺,但是key不變的情況。
    具體如下:

  • 如果按照Key來(lái)排序罗岖,則相同的Key的Value值將會(huì)發(fā)生覆蓋怀大,即value值等于最近put方法的指定的value值,Key不變呀闻;
  • 如果按照Value來(lái)排序化借,則相同的Value的key將會(huì)發(fā)生覆蓋,注意和1的區(qū)別:key還是原來(lái)的key,value還是原來(lái)的value捡多,只是進(jìn)行了一次沒(méi)有意義的value = value 的等值賦值的過(guò)程蓖康。

TreeMap紅黑樹(shù)部分方法詳解參考鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末铐炫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蒜焊,更是在濱河造成了極大的恐慌倒信,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泳梆,死亡現(xiàn)場(chǎng)離奇詭異鳖悠,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)优妙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)乘综,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人套硼,你說(shuō)我怎么就攤上這事卡辰。” “怎么了邪意?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵九妈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我雾鬼,道長(zhǎng)萌朱,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任策菜,我火速辦了婚禮嚷兔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘做入。我一直安慰自己,他們只是感情好同衣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布竟块。 她就那樣靜靜地躺著,像睡著了一般耐齐。 火紅的嫁衣襯著肌膚如雪浪秘。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,521評(píng)論 1 304
  • 那天埠况,我揣著相機(jī)與錄音耸携,去河邊找鬼。 笑死辕翰,一個(gè)胖子當(dāng)著我的面吹牛夺衍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播喜命,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼沟沙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼河劝!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起矛紫,我...
    開(kāi)封第一講書(shū)人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤赎瞎,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后颊咬,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體务甥,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年喳篇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了敞临。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杭隙,死狀恐怖哟绊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情痰憎,我是刑警寧澤票髓,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站铣耘,受9級(jí)特大地震影響洽沟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜗细,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一裆操、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧炉媒,春花似錦踪区、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至白粉,卻和暖如春传泊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸭巴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工眷细, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鹃祖。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓溪椎,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子池磁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

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

  • 前面已經(jīng)介紹完了Collection接口下的集合實(shí)現(xiàn)類(lèi)奔害,今天我們來(lái)介紹Map接口下的兩個(gè)重要的集合實(shí)現(xiàn)類(lèi)HashM...
    Ruheng閱讀 10,457評(píng)論 2 38
  • 本文轉(zhuǎn)自 https://zhuanlan.zhihu.com/p/21673805 美團(tuán)點(diǎn)評(píng)技術(shù)團(tuán)隊(duì)· 3 個(gè)月...
    抓兔子的貓閱讀 1,059評(píng)論 0 1
  • HashMap 是 Java 面試必考的知識(shí)點(diǎn),面試官?gòu)倪@個(gè)小知識(shí)點(diǎn)就可以了解我們對(duì) Java 基礎(chǔ)的掌握程度地熄。網(wǎng)...
    野狗子嗷嗷嗷閱讀 6,667評(píng)論 9 107
  • 生活中我們常常聽(tīng)到‘‘少吃糖端考,糖吃多了會(huì)變胖’’ 我們還會(huì)聽(tīng)到‘‘多吃膳食纖維雅潭,它可以幫助你減肥’’ 其實(shí)他們有一...
    鄧秋云閱讀 1,189評(píng)論 0 2
  • 你思念的人并不愛(ài)你 或者根本沒(méi)有想起你 真的思念泛濫 與其相見(jiàn) 不如懷念
    子衿兒閱讀 140評(píng)論 0 0