TreeMap是底層基於TreeMap的NavigableSet實現,容器的元素存儲在TreeMap鍵值對映射的key中,它使用元素的天然順序或者傳入的比較器Comparator對元素進行排序。它爲基本操做例如add、remove、contain提供了log(n)的時間複雜度保證。注意TreeSet不是線程同步的容器,若是有多個線程同時訪問它,且至少有一個線程修改了容器的結構,那麼他必須在外部進行同步處理。通常都是經過對天然封裝該Set實例的對象進行同步操做來完成,若是沒有這樣的對象,那麼可使用Collections.synChronizedSortedSet包裝TreeSet爲一個線程安全的容器。java
該TreeSet容器返回的迭代器是快速失敗的(fail-fast),即在生成迭代器以後,若是該容器發生告終構部性修改除了經過迭代iterator.remove方法刪除元素以外,迭代器將會拋出ConcurrentModificationException異常,該異常並不能絕對保證,應該只用於檢測異常。安全
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable { /** 內部TreeMap實例 **/ private transient NavigableMap<E,Object> m; //靜態對象充當TreeMap實例中的鍵值對中的value,全部key的value都是該對象 private static final Object PRESENT = new Object(); }
TreeSet繼承自AbstractSet,AbstractSet提供了Set的一些基本方法實現,大大減小實現TreeSet的工做量,此外它實現了NavigableSet接口,擴展了倒序、獲取給定目標最接近匹配等功能,實現了Clonable支持克隆、java.io.Serializable支持序列化數據結構
/** * 構造方法,指定NavigableMap實例 */ TreeSet(NavigableMap<E,Object> m) { this.m = m; } /** * 無參構造方法,默認建立一個TreeMap實例 */ public TreeSet() { this(new TreeMap<E,Object>()); } /** * 構造方法,建立一個空的TreeMap實例並按照方法指定的比較器對元素進行排序 */ public TreeSet(Comparator<? super E> comparator) { this(new TreeMap<>(comparator)); } /** * 構造方法,建立一個空的TreeSet實例,並將方法指定集合c的全部元素填充到TreeSet實例中 */ public TreeSet(Collection<? extends E> c) { this(); addAll(c); } /** * 構造方法,建立一個空的TreeSet實例,比較器取方法參數SortedSet對象的s的內部比較器, * 將容器s中的全部元素填充到內部TreeMap實例 */ public TreeSet(SortedSet<E> s) { this(s.comparator()); addAll(s); }
經過對TreeSet構造函數的分析,咱們能夠了解到TreeSet的底層與HashSet相似,只不過它的底層存儲結構是一個NavagableMap實例,通常是TreeMap對象,全部TreeSet的操做最終都是反映到底層對TreeMap的操做。函數
/** * 返回一個遍歷當前容器元素的迭代器 */ public Iterator<E> iterator() { return m.navigableKeySet().iterator(); } /** * 判斷當前容器是否爲空 */ public boolean isEmpty() { return m.isEmpty(); } /** * 返回當前容器是否包含指定元素 */ public boolean contains(Object o) { return m.containsKey(o); } /** * 添加元素 */ public boolean add(E e) { return m.put(e, PRESENT)==null; } /** * 刪除元素 */ public boolean remove(Object o) { return m.remove(o)==PRESENT; } /** * 獲取容器第一個元素 */ public E first() { return m.firstKey(); } /** * 獲取容器最後一個元素 */ public E last() { return m.lastKey(); }
經過對TreeSet成員方法的分析,咱們能夠發現它們的實現徹底依賴於底層的NavigableMap實例(通常狀況下能夠簡單視爲TreeMap實例),容器元素對應的是TreeMap實例鍵值對的Key,若想研讀底層實現能夠直接去研讀TreeMap響應方法的源碼。源碼分析