探索TreeSet底層實現
阿新 • • 發佈:2020-12-21
前言
TreeSet的內部實現基於TreeMap,所以它的資料結構是紅黑樹
。註釋也不總結了,此探索是基於JDK1.8
,直接進入正題。
資料結構
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable { //儲存元素 private transient NavigableMap<E,Object> m; //既然用了TreeMap就要考慮值應該存什麼,就是它了,不管新增的元素是什麼,它都作為值 private static final Object PRESENT = new Object(); }
建構函式
/** * 指定NavigableMap實現類來初始化 * ConcurrentSkipListMap是NavigableMap的實現類!!!埋下伏筆 * @param m 指定實現類 */ TreeSet(NavigableMap<E,Object> m) { this.m = m; } /** * 預設初始化 */ public TreeSet() { this(new TreeMap<E,Object>()); } /** * 指定比較器進行初始化 * @param comparator 比較器 */ public TreeSet(Comparator<? super E> comparator) { this(new TreeMap<>(comparator)); } /** * 新增指定集合進行初始化 * @param c 指定集合 */ public TreeSet(Collection<? extends E> c) { this(); addAll(c); } /** * 指定Set集合進行初始化 * @param s Set集合 */ public TreeSet(SortedSet<E> s) { this(s.comparator()); addAll(s); }
簡單方法
/** * 獲取迭代器 * @return 迭代器 */ public Iterator<E> iterator() { return m.navigableKeySet().iterator(); } /** * 獲取按降序排列的迭代器 * @return 降序排列的迭代器 */ public Iterator<E> descendingIterator() { return m.descendingKeySet().iterator(); } /** * 獲取按降序排列的Set集合 * @return 降序排列的Set集合 */ public NavigableSet<E> descendingSet() { return new TreeSet<>(m.descendingMap()); } /** * TreeSet集合的長度 * @return 元素個數 */ public int size() { return m.size(); } /** * TreeSet集合是否為空 * @return 是否為空 */ public boolean isEmpty() { return m.isEmpty(); } /** * TreeSet是否包含指定元素 * @param o 指定元素 * @return 是否包含指定元素 */ public boolean contains(Object o) { return m.containsKey(o); } /** * 新增元素 * @param e 指定元素 * @return 是否新增成功 */ public boolean add(E e) { return m.put(e, PRESENT)==null; } /** * 移除指定元素 * @param o 指定元素 * @return 是否移除成功 */ public boolean remove(Object o) { return m.remove(o)==PRESENT; } /** * 清空 */ public void clear() { m.clear(); } /** * 批量新增指定集合 * @param c 指定集合 * @return 是否新增成功 */ public boolean addAll(Collection<? extends E> c) { // Use linear-time version if applicable if (m.size()==0 && c.size() > 0 && c instanceof SortedSet && m instanceof TreeMap) { SortedSet<? extends E> set = (SortedSet<? extends E>) c; TreeMap<E,Object> map = (TreeMap<E, Object>) m; Comparator<?> cc = set.comparator(); Comparator<? super E> mc = map.comparator(); if (cc==mc || (cc != null && cc.equals(mc))) { map.addAllForTreeSet(set, PRESENT); //指定集合來新增一顆紅黑樹 return true; } } return super.addAll(c); } /** * 指定起始元素與結束元素及是否包含起始、結束元素來獲取當前物件的子集 * 當前物件是已經排好序了 * @param fromElement 起始元素 * @param fromInclusive 子集中是否包含起始元素 * @param toElement 結束元素 * @param toInclusive 子集中是否包含結束元素 * @return 子集物件 */ public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { return new TreeSet<>(m.subMap(fromElement, fromInclusive, toElement, toInclusive)); } /** * 指定結束元素及是否包含結束元素來獲取當前物件的子集 * 當前物件是已經排好序了,相當於起始元素已經指定好了 * * @param toElement 結束元素 * @param inclusive 子集中是否包含結束元素 * @return 子集物件 */ public NavigableSet<E> headSet(E toElement, boolean inclusive) { return new TreeSet<>(m.headMap(toElement, inclusive)); } /** * 指定起始元素及是否包含起始元素來獲取當前物件的子集 * 相當於介紹元素已經指定好了 * @param fromElement 起始元素 * @param inclusive 子集中是否包含起始元素 * @return 子集物件 */ public NavigableSet<E> tailSet(E fromElement, boolean inclusive) { return new TreeSet<>(m.tailMap(fromElement, inclusive)); } /** * 指定起始元素與結束元素來獲取當前物件的子集 * 包含起始元素、不包含結束元素 * @param fromElement 起始元素 * @param toElement 結束元素 * @return 子集物件 */ public SortedSet<E> subSet(E fromElement, E toElement) { return subSet(fromElement, true, toElement, false); } /** * 獲取比較器 * @return 比較器 */ public Comparator<? super E> comparator() { return m.comparator(); } /** * 獲取排序後的第一個元素 * @return 排序後的第一個元素 */ public E first() { return m.firstKey(); } /** * 獲取排序後的最後一個元素 * @return 排序後的最後一個元素 */ public E last() { return m.lastKey(); } /** * 獲取小於指定元素的最大值 * @param key 指定元素 * @return 小於指定元素的最大值 */ public E lower(E e) { return m.lowerKey(e); } /** * 獲取等於或小於指定元素的最大值 * @param key 指定元素 * @return 等於或小於指定元素的最大值 */ public E floor(E e) { return m.floorKey(e); } /** * 獲取等於或大於指定元素的最小值 * @param key 指定元素 * @return 等於或大於指定元素的最小值 */ public E ceiling(E e) { return m.ceilingKey(e); } /** * 獲取大於指定元素的最小值 * @param key 指定元素 * @return 大於指定元素的最小值 */ public E higher(E e) { return m.higherKey(e); } /** * 獲取排序後的第一個元素並移除 * 獲取最左邊的元素並移除 * @return 最左邊的元素 */ public E pollFirst() { Map.Entry<E,?> e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); } /** * 獲取排序後的最後一個元素並移除 * 獲取最右邊的元素並移除 * @return 最右邊的元素 */ public E pollLast() { Map.Entry<E,?> e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); }
總結
-
TreeSet底層是TreeMa,所以它的資料結構是紅黑樹。
-
TreeSet有序、不可重複、非執行緒安全。
-
TreeSet預設按照自然順序排列元素,可指定比較器來自定義排序。
重點關注
基於TreeMap