Java集合框架:TreeMap
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。
歡迎跳轉到本文的原文鏈接:https://honeypps.com/java/java-collection-treemap/
TreeMap定義
package java.util; public class TreeMap<K,V>extends AbstractMap<K,V>implements NavigableMap<K,V>, Cloneable, java.io.Serializable{ } public interface NavigableMap<K,V> extends SortedMap<K,V>{}??TreeMap繼承AbstractMap,實現NavigableMap、Cloneable、Serializable三個接口。其中AbstractMap表明TreeMap為一個Map即支持key-value的集合, NavigableMap則意味著它支持一系列的導航方法,具備針對給定搜索目標返回最接近匹配項的導航方法 。
??TreeMap中同時也包含了如下幾個重要的屬性:
//比較器,因為TreeMap是有序的,通過comparator接口我們可以對TreeMap的內部排序進行精密的控制
private final Comparator<? super K> comparator;
//TreeMap紅-黑節點,為TreeMap的內部類
private transient Entry<K,V> root = null;
//容器大小
private transient int size = 0;
//TreeMap修改次數
private transient int modCount = 0;
//紅黑樹的節點顏色–紅色
private static final boolean RED = false;
//紅黑樹的節點顏色–黑色
private static final boolean BLACK = true;
??對于實體節點Entry是TreeMap的內部類,它有幾個重要的屬性:
//鍵
K key;
//值
V value;
//左孩子
Entry<K,V> left = null;
//右孩子
Entry<K,V> right = null;
//父親
Entry<K,V> parent;
//顏色
boolean color = BLACK;
??關于紅黑樹的實現可以搜索一些相關資料,我覺得參考資料3就不錯,博主就不贅述了。
TreeMap特點
可以采用這種方式將TreeMap設置為同步的:Map m = Collections.synchronizedSortedMap(new TreeMap(…));
TreeMap是SortedMap接口的基于紅黑樹的實現。此類保證了映射按照升序順序排列關鍵字, 根據使用的構造方法不同,可能會按照鍵的類的自然順序進行排序,或者按照創建時所提供的比較器(自定義)進行排序。
先舉個案例說明一下:
??輸出結果:
1:null 2:3 3:2 10:1??也可以采用自定義的類,引用《Comparable與Comparator淺析》中的Person1舉例:
public class Person1 implements Comparable<Person1> {private int age;private String name;public Person1(String name, int age){this.name = name;this.age = age;}@Overridepublic int compareTo(Person1 o){return this.age-o.age;}@Override public String toString(){return name+":"+age;} }?? 測試代碼:
Map<Person1,Integer> map = new TreeMap<>();Person1 person1 = new Person1("zzh",18);Person1 person2 = new Person1("jj",17);Person1 person3 = new Person1("qq",19);map.put(person1, 1);map.put(person2, 2);map.put(person3, 3);for(Entry<Person1, Integer> entry:map.entrySet()){System.out.println(entry.getKey()+":"+entry.getValue());}??測試結果:
jj:17:2 zzh:18:1 qq:19:3??只要自定義鍵的類實現了Comparable接口就可以使用TreeMap的排序功能,也可以通過Comparator接口實現(關于Comparable和Comparator的區別可以翻看《Comparable與Comparator淺析》),如下:
??首先引用類Person2:
??測試代碼:
Map<Person2,Integer> map2 = new TreeMap<>(new Comparator<Person2>(){@Overridepublic int compare(Person2 o1, Person2 o2){if(o1 == null || o2 == null)return 0;return o1.getAge()-o2.getAge();}});Person2 p1 = new Person2("zzh",18);Person2 p2 = new Person2("jj",17);Person2 p3 = new Person2("qq",19);map2.put(p1, 1);map2.put(p2, 2);map2.put(p3, 3);for(Entry<Person2, Integer> entry:map2.entrySet()){System.out.println(entry.getKey()+":"+entry.getValue());}??輸出結果:
jj:17:2 zzh:18:1 qq:19:3??可以看到Person2中并沒有實現Comparable接口,但是想要和Person1一樣能夠和TreeMap合作,只需要在創建TreeMap的構造函數中聲明一個Comparator接口的實現,譬如上面的例子所示。
3. 由所有此類的“collection 視圖方法”所返回的迭代器都是快速失敗的。
??這點和HashMap一樣,所謂快速失敗就是在并發集合中,其進行迭代操作時,若有其他線程對其結構性的修改,這是迭代器會立馬感知到,并且立刻拋出ConcurrentModificationException異常,而不是等待迭代完成之后才告訴你已經出錯。注意,迭代器的快速失敗行為無法得到保證,因為一般來說,不可能對是否出現不同步并發修改做出任何硬性保證。 快速失敗迭代器會盡最大努力拋出 ConcurrentModificationException。 因此,為提高這類迭代器的正確性而編寫一個依賴于此異常的程序是錯誤的做法:迭代器的快速失敗行為應該僅用于檢測 bug。
4. 和HashMap一樣,如果插入重復的元素,后面的元素會覆蓋前面的。
5. 鍵不可以為null(如果比較器對null做了處理,就可以為null),但是值可以為null。
??如上面的案例中,加入:
??在打印map2的時候就不會報錯。
6. TreeMap對containsKey、get、put 和 remove 操作提供了保證的 log(n) 時間開銷。
??TreeMap提供了很多方法方便大小使用,譬如containsKey, get, put,remove,entrySet等Map通用的方法,也包括fisrtEntry, firstKey, cellingKey, lowerKey等方法,由于篇幅較大,不便贅述,使用前最好翻看一下API或者源碼熟悉一下。
HashMap與TreeMap的區別
HashMap:基于哈希表實現。使用HashMap要求添加的鍵類明確定義了hashCode()和equals()[可以重寫hashCode()和equals()],為了優化HashMap空間的使用,您可以調優初始容量和負載因子。
(1)HashMap(): 構建一個空的哈希映像
(2)HashMap(Map m): 構建一個哈希映像,并且添加映像m的所有映射
(3)HashMap(int initialCapacity): 構建一個擁有特定容量的空的哈希映像
(4)HashMap(int initialCapacity, float loadFactor): 構建一個擁有特定容量和加載因子的空的哈希映像
TreeMap:基于紅黑樹實現。TreeMap沒有調優選項,因為該樹總處于平衡狀態。
(1)TreeMap():構建一個空的映像樹
(2)TreeMap(Map m): 構建一個映像樹,并且添加映像m中所有元素
(3)TreeMap(Comparator c): 構建一個映像樹,并且使用特定的比較器對關鍵字進行排序
(4)TreeMap(SortedMap s): 構建一個映像樹,添加映像樹s中所有映射,并且使用與有序映像s相同的比較器排序
HashMap:適用于在Map中插入、刪除和定位元素。
TreeMap:適用于按自然順序或自定義順序遍歷鍵(key)。
HashMap通常比TreeMap快一點(樹和哈希表的數據結構使然),建議多使用HashMap,在需要排序的Map時候才用TreeMap.
參考資料
歡迎跳轉到本文的原文鏈接:https://honeypps.com/java/java-collection-treemap/
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。
總結
以上是生活随笔為你收集整理的Java集合框架:TreeMap的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java集合框架:LinkedHashM
- 下一篇: Java集合框架:WeakHashMap