聲明,本文用得是jdk1.8html
前面章節回顧:java
本篇主要講解TreeMap~微信
看這篇文章以前最好是有點數據結構的基礎:數據結構
固然了,若是講得有錯的地方還請你們多多包涵並不吝在評論去指正~post
按照慣例,我簡單翻譯了一下頂部的註釋(我英文水平渣,若是有錯的地方請多多包涵~歡迎在評論區下指正)this
接着咱們來看看類繼承圖:spa
在註釋中提到的要點,我來總結一下:.net
對我而言,Comparator和Comparable我都忘得差很少了~~~下面就開始看TreeMap的源碼來看看它是怎麼實現的,而且回顧一下Comparator和Comparable的用法吧!翻譯
TreeMap的構造方法有4個:debug
能夠發現,TreeMap的構造方法大多數與comparator有關:
也就是頂部註釋說的:TreeMap有序是經過Comparator來進行比較的,若是comparator爲null,那麼就使用天然順序~
打個比方:
TreeMap<Integer, Integer> treeMap = new TreeMap<>(); treeMap.put(1, 5); treeMap.put(2, 4); treeMap.put(3, 3); treeMap.put(4, 2); treeMap.put(5, 1); for (Entry<Integer, Integer> entry : treeMap.entrySet()) { String s = entry.getKey() +"關注公衆號:Java3y---->" + entry.getValue(); System.out.println(s); }
咱們來看看TreeMap的核心put方法,閱讀它就能夠獲取很多關於TreeMap特性的東西了~
下面是compare(Object k1, Object k2)
方法
/** * Compares two keys using the correct comparison method for this TreeMap. */ @SuppressWarnings("unchecked") final int compare(Object k1, Object k2) { return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2) : comparator.compare((K)k1, (K)k2); }
若是咱們設置key爲null,會拋出異常的,就不執行下面的代碼了。
接下來咱們來看看get方法的實現:
點進去getEntry()
看看實現:
若是Comparator不爲null,接下來咱們進去看看getEntryUsingComparator(Object key)
,是怎麼實現的
刪除節點的時候調用的是deleteEntry(Entry<K,V> p)
方法,這個方法主要是刪除節點而且平衡紅黑樹
平衡紅黑樹的代碼是比較複雜的,我就不說了,大家去看吧(反正我看不懂)....
在看源碼的時候可能不知道哪一個是核心的遍歷方法,由於Iterator有很是很是多~
此時,咱們只須要debug一下看看,跟下去就好!
因而乎,咱們能夠找到:TreeMap遍歷是使用EntryIterator這個內部類的
首先來看看EntryIterator的類結構圖吧:
能夠發現,EntryIterator大多的實現都是在父類中:
那接下來咱們去看看PrivateEntryIterator比較重要的方法:
咱們進去successor(e)
方法看看實現:
successor 其實就是一個結點的 下一個結點,所謂 下一個,是按次序排序後的下一個結點。從代碼中能夠看出,若是右子樹不爲空,就返回右子樹中最小結點。若是右子樹爲空,就要向上回溯了。在這種狀況下,t 是以其爲根的樹的最後一個結點。若是它是其父結點的左孩子,那麼父結點就是它的下一個結點,不然,t 就是以其父結點爲根的樹的最後一個結點,須要再次向上回溯。一直到 ch 是 p 的左孩子爲止。
TreeMap底層是紅黑樹,可以實現該Map集合有序~
若是在構造方法中傳遞了Comparator對象,那麼就會以Comparator對象的方法進行比較。不然,則使用Comparable的compareTo(T o)
方法來比較。
compareTo(T o)
方法來比較,key必定是不能爲null,而且得實現了Comparable接口的。compareTo(T o)
方法來比較,key也是不能爲null的public static void main(String[] args) { TreeMap<Student, String> map = new TreeMap<Student, String>((o1, o2) -> { //主要條件 int num = o1.getAge() - o2.getAge(); //次要條件 int num2 = num == 0 ? o1.getName().compareTo(o2.getName()) : num; return num2; }); //建立學生對象 Student s1 = new Student("潘安", 30); Student s2 = new Student("柳下惠", 35); //添加元素進集合 map.put(s1, "宋朝"); map.put(s2, "元朝"); map.put(null, "漢朝"); //獲取key集合 Set<Student> set = map.keySet(); //遍歷key集合 for (Student student : set) { String value = map.get(student); System.out.println(student + "---------" + value); } }
咱們從源碼中的不少地方中發現:Comparator和Comparable出現的頻率是很高的,由於TreeMap實現有序要麼就是外界傳遞進來Comparator對象,要麼就使用默認key的Comparable接口(實現天然排序)
最後我就來總結一下TreeMap要點吧:
參考資料:
明天要是無心外的話,可能會寫ConcurrentHashMap集合,敬請期待哦~~~~
文章的目錄導航:zhongfucheng.bitcron.com/post/shou-j…
若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:Java3y。爲了你們方便,剛新建了一下qq羣:742919422,你們也能夠去交流交流。謝謝支持了!但願能多介紹給其餘有須要的朋友