TreeMap源碼分析(JDK1.8)

成員變量

1、comparator

/**
 * 比較器,如果沒指定比較器則key要實現Comparable接口重寫compareTo方法
 * TreeMap有兩種方式定義key的比較規則:1:key實現Comparable接口重寫compareTo方法;2:通過構造方法指定構造器
 */
private final Comparator<? super K> comparator;

2、root

/**
 * 根節點,所有元素都存儲在以root爲根節點的紅黑樹中
 */
private transient Entry<K,V> root;

3、size

/**
 * 實際元素的個數
 */
private transient int size = 0;

4、modCount

/**
 * 修改次數,用於快速失敗校驗
 */
private transient int modCount = 0;

構造方法

1、TreeMap()

/**
 * 無參構造方法,key必須實現Comparable接口重寫compareTo方法
 */
public TreeMap() {
  comparator = null;
}

2、TreeMap(Comparator<? super K> comparator)

/**
 * 有參構造方法,使用指定的比較器來對key進行比較
 */
public TreeMap(Comparator<? super K> comparator) {
  this.comparator = comparator;
}

3、TreeMap(Map<? extends K, ? extends V> m)

/**
 * 將傳入的Map集合中的元素添加到TreeMap中,key必須實現Comparable接口重寫compareTo方法
 */
public TreeMap(Map<? extends K, ? extends V> m) {
  comparator = null;
  putAll(m);
}

4、TreeMap(SortedMap<K, ? extends V> m)

/**
 * 將傳入的Map集合中的元素添加到TreeMap中,使用傳入的Map集合中使用的比較器
 */
public TreeMap(SortedMap<K, ? extends V> m) {
  comparator = m.comparator();
  try {
    buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
  } catch (java.io.IOException cannotHappen) {
  } catch (ClassNotFoundException cannotHappen) {
  }
}

內部類

1、Entry

/**
 * 存在TreeMap中的元素其實都可以看做是一個Entry對象元素
 */
static final class Entry<K,V> implements Map.Entry<K,V> {
  K key;
  V value;
  Entry<K,V> left;
  Entry<K,V> right;
  Entry<K,V> parent;
  boolean color = BLACK;

  Entry(K key, V value, Entry<K,V> parent) {
    this.key = key;
    this.value = value;
    this.parent = parent;
  }

  public K getKey() {
    return key;
  }

  public V getValue() {
    return value;
  }

  public V setValue(V value) {
    V oldValue = this.value;
    this.value = value;
    return oldValue;
  }

  public boolean equals(Object o) {
    if (!(o instanceof Map.Entry))
      return false;
    Map.Entry<?,?> e = (Map.Entry<?,?>)o;

    return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
  }

  public int hashCode() {
    int keyHash = (key==null ? 0 : key.hashCode());
    int valueHash = (value==null ? 0 : value.hashCode());
    return keyHash ^ valueHash;
  }

  public String toString() {
    return key + "=" + value;
  }
}

2、EntrySet

/**
 * 靜態內部類EntrySet,返回一個空的內部實現類,該內部類在返回的時候內部並沒有元素,同時TreeMap在put()的時候也並未特意將元素添加到內部類中,它是在迭代器遍歷的時候遍歷root根節點中的Entry元素,也可以使用foreach遍歷(底層也是使用迭代器遍歷)
 */
class EntrySet extends AbstractSet<Map.Entry<K,V>> {
  public Iterator<Map.Entry<K,V>> iterator() {
    return new EntryIterator(getFirstEntry());
  }

  public boolean contains(Object o) {
    if (!(o instanceof Map.Entry))
      return false;
    Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
    Object value = entry.getValue();
    Entry<K,V> p = getEntry(entry.getKey());
    return p != null && valEquals(p.getValue(), value);
  }

  public boolean remove(Object o) {
    if (!(o instanceof Map.Entry))
      return false;
    Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
    Object value = entry.getValue();
    Entry<K,V> p = getEntry(entry.getKey());
    if (p != null && valEquals(p.getValue(), value)) {
      deleteEntry(p);
      return true;
    }
    return false;
  }

  public int size() {
    return TreeMap.this.size();
  }

  public void clear() {
    TreeMap.this.clear();
  }

  public Spliterator<Map.Entry<K,V>> spliterator() {
    return new EntrySpliterator<K,V>(TreeMap.this, null, null, 0, -1, 0);
  }
}

3、KeySet

/**
 * 靜態內部類KeySet,返回一個空的內部實現類,該內部類在返回的時候內部並沒有元素,同時TreeMap在put()的時候也並未特意將元素添加到內部類中,它是在迭代器遍歷的時候遍歷root根節點中的Entry元素,也可以使用foreach遍歷(底層也是使用迭代器遍歷)
 */
static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> {
  private final NavigableMap<E, ?> m;
  KeySet(NavigableMap<E,?> map) { m = map; }

  public Iterator<E> iterator() {
    if (m instanceof TreeMap)
      return ((TreeMap<E,?>)m).keyIterator();
    else
      return ((TreeMap.NavigableSubMap<E,?>)m).keyIterator();
  }

  public Iterator<E> descendingIterator() {
    if (m instanceof TreeMap)
      return ((TreeMap<E,?>)m).descendingKeyIterator();
    else
      return ((TreeMap.NavigableSubMap<E,?>)m).descendingKeyIterator();
  }

  public int size() { return m.size(); }
  public boolean isEmpty() { return m.isEmpty(); }
  public boolean contains(Object o) { return m.containsKey(o); }
  public void clear() { m.clear(); }
  public E lower(E e) { return m.lowerKey(e); }
  public E floor(E e) { return m.floorKey(e); }
  public E ceiling(E e) { return m.ceilingKey(e); }
  public E higher(E e) { return m.higherKey(e); }
  public E first() { return m.firstKey(); }
  public E last() { return m.lastKey(); }
  public Comparator<? super E> comparator() { return m.comparator(); }
  public E pollFirst() {
    Map.Entry<E,?> e = m.pollFirstEntry();
    return (e == null) ? null : e.getKey();
  }
  public E pollLast() {
    Map.Entry<E,?> e = m.pollLastEntry();
    return (e == null) ? null : e.getKey();
  }
  public boolean remove(Object o) {
    int oldSize = size();
    m.remove(o);
    return size() != oldSize;
  }
  public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
                                E toElement,   boolean toInclusive) {
    return new KeySet<>(m.subMap(fromElement, fromInclusive,
                                 toElement,   toInclusive));
  }
  public NavigableSet<E> headSet(E toElement, boolean inclusive) {
    return new KeySet<>(m.headMap(toElement, inclusive));
  }
  public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
    return new KeySet<>(m.tailMap(fromElement, inclusive));
  }
  public SortedSet<E> subSet(E fromElement, E toElement) {
    return subSet(fromElement, true, toElement, false);
  }
  public SortedSet<E> headSet(E toElement) {
    return headSet(toElement, false);
  }
  public SortedSet<E> tailSet(E fromElement) {
    return tailSet(fromElement, true);
  }
  public NavigableSet<E> descendingSet() {
    return new KeySet<>(m.descendingMap());
  }

  public Spliterator<E> spliterator() {
    return keySpliteratorFor(m);
  }
}

4、Values

/**
 * 靜態內部類Values,返回一個空的內部實現類,該內部類在返回的時候內部並沒有元素,同時TreeMap在put()的時候也並未特意將元素添加到內部類中,它是在迭代器遍歷的時候遍歷root根節點中的Entry元素,也可以使用foreach遍歷(底層也是使用迭代器遍歷)
 */
class Values extends AbstractCollection<V> {
  public Iterator<V> iterator() {
    return new ValueIterator(getFirstEntry());
  }

  public int size() {
    return TreeMap.this.size();
  }

  public boolean contains(Object o) {
    return TreeMap.this.containsValue(o);
  }

  public boolean remove(Object o) {
    for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e)) {
      if (valEquals(e.getValue(), o)) {
        deleteEntry(e);
        return true;
      }
    }
    return false;
  }

  public void clear() {
    TreeMap.this.clear();
  }

  public Spliterator<V> spliterator() {
    return new ValueSpliterator<K,V>(TreeMap.this, null, null, 0, -1, 0);
  }
}

常用方法

1、get(Object key)

  • get(Object key)方法執行流程
  • get(Object key)方法源碼分析
/**
 * 根據key來獲取value元素
 */
public V get(Object key) {
  // 根據key來獲取Entry元素
  Entry<K,V> p = getEntry(key);
  
  return (p==null ? null : p.value);
}

/**
 * 根據key來獲取Entry元素
 */
final Entry<K,V> getEntry(Object key) {
  if (comparator != null)
    return getEntryUsingComparator(key);
  // 下面的代碼爲根據key實現Comparable接口重寫compareTo方法來比較key元素的方式
  if (key == null)
    throw new NullPointerException();
  Comparable<? super K> k = (Comparable<? super K>) key;
  Entry<K,V> p = root;
  while (p != null) {
    // 這裏cmp爲傳入的key與節點元素中的key根據key中重寫的compareTo方法所比較的大小
    int cmp = k.compareTo(p.key);
    // 根據cmp的大小來判斷遍歷左子樹還是右子樹
    if (cmp < 0)
      p = p.left;
    else if (cmp > 0)
      p = p.right;
    else
      return p;
  }
  return null;
}

/**
 * 使用指定的Comparator比較器來比較key
 */
final Entry<K,V> getEntryUsingComparator(Object key) {
  K k = (K) key;
  Comparator<? super K> cpr = comparator;
  if (cpr != null) {
    Entry<K,V> p = root;
    while (p != null) {
      // 這裏cmp爲指定的比較器來比較傳入的key和節點元素中key元素的大小
      int cmp = cpr.compare(k, p.key);
      // 根據cmp的大小來判斷遍歷左子樹還是右子樹
      if (cmp < 0)
        p = p.left;
      else if (cmp > 0)
        p = p.right;
      else
        return p;
    }
  }
  return null;
}

2、put(K key, V value)

/**
 * 添加單個元素
 */
public V put(K key, V value) {
  Entry<K,V> t = root;
    
  // root根節點爲null,這是第一次執行put()操作的時候
  if (t == null) {
    compare(key, key);
	  // 第一次執行put()時,將該節點設置爲root根節點
    root = new Entry<>(key, value, null);
    
    size = 1;
    modCount++;
    return null;
  }
  int cmp;
  Entry<K,V> parent;
  Comparator<? super K> cpr = comparator;
  
  // 使用指定的比較器來比較大小,當root紅黑樹中存在此元素時直接替換
  if (cpr != null) {
    do {
      parent = t;
      cmp = cpr.compare(key, t.key);
      // 小於0從當前節點的左子樹尋找
      if (cmp < 0)
        t = t.left;
      // 大於0從當前節點的右子樹尋找
      else if (cmp > 0)
        t = t.right;
      // 等於0,直接更換其value值並返回舊值
      else
        return t.setValue(value);
    } while (t != null);
  }
  
  // 根據key中重寫的compareTo方法所比較的大小,當root紅黑樹中存在此元素時直接替換
  else {
    if (key == null)
      throw new NullPointerException();
    Comparable<? super K> k = (Comparable<? super K>) key;
    do {
      parent = t;
      cmp = k.compareTo(t.key);
      // 小於0從當前節點的左子樹尋找
      if (cmp < 0)
        t = t.left;
      // 大於0從當前節點的右子樹尋找
      else if (cmp > 0)
        t = t.right;
      // 等於0,直接更換其value值並返回舊值
      else
        return t.setValue(value);
    } while (t != null);
  }
  
  // 當root紅黑樹中不存在此元素時
  // 創建Entry對象
  Entry<K,V> e = new Entry<>(key, value, parent);
  
  // 此時cmp爲比較之後的最後一個節點,小於0將新加的Entry元素添加到左子樹
  if (cmp < 0)
    parent.left = e;
  // 大於0將新加的Entry元素添加到右子樹
  else
    parent.right = e;
  
  // 待添加好元素後,平衡紅黑樹
  fixAfterInsertion(e);
  
  size++;
  modCount++;
  return null;
}

/**
 * 比較k1和k2
 */
final int compare(Object k1, Object k2) {
  return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
    : comparator.compare((K)k1, (K)k2);
}

/**
 * 平衡紅黑樹
 */
private void fixAfterInsertion(Entry<K,V> x) {
  x.color = RED;

  while (x != null && x != root && x.parent.color == RED) {
    if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
      Entry<K,V> y = rightOf(parentOf(parentOf(x)));
      if (colorOf(y) == RED) {
        setColor(parentOf(x), BLACK);
        setColor(y, BLACK);
        setColor(parentOf(parentOf(x)), RED);
        x = parentOf(parentOf(x));
      } else {
        if (x == rightOf(parentOf(x))) {
          x = parentOf(x);
          rotateLeft(x);
        }
        setColor(parentOf(x), BLACK);
        setColor(parentOf(parentOf(x)), RED);
        rotateRight(parentOf(parentOf(x)));
      }
    } else {
      Entry<K,V> y = leftOf(parentOf(parentOf(x)));
      if (colorOf(y) == RED) {
        setColor(parentOf(x), BLACK);
        setColor(y, BLACK);
        setColor(parentOf(parentOf(x)), RED);
        x = parentOf(parentOf(x));
      } else {
        if (x == leftOf(parentOf(x))) {
          x = parentOf(x);
          rotateRight(x);
        }
        setColor(parentOf(x), BLACK);
        setColor(parentOf(parentOf(x)), RED);
        rotateLeft(parentOf(parentOf(x)));
      }
    }
  }
  root.color = BLACK;
}

3、putAll(Map map)

/**
 * 批量添加元素
 */
public void putAll(Map<? extends K, ? extends V> map) {
    int mapSize = map.size();
  
    // 當該TreeMap對象中size爲0,並且傳入的SortedMap對象不爲空時
    if (size==0 && mapSize!=0 && map instanceof SortedMap) {
        Comparator<?> c = ((SortedMap<?,?>)map).comparator();
        
        // comparator和SortedMap對象的比較器一致
        if (c == comparator || (c != null && c.equals(comparator))) {
            ++modCount;
            try {
                buildFromSorted(mapSize, map.entrySet().iterator(), null, null);
            } catch (java.io.IOException cannotHappen) {
            } catch (ClassNotFoundException cannotHappen) {
            }
            return;
        }
    }

    // 調用父類AbstractMap中的putAll()方法
    super.putAll(map);
}

/**
 * 根據傳入的SortedMap構建TreeMap對象
 */
private void buildFromSorted(int size, Iterator<?> it, java.io.ObjectInputStream str, V defaultVal) throws  java.io.IOException, ClassNotFoundException {
  this.size = size;

	// 根據傳入的SortedMap構建TreeMap對象實現
  root = buildFromSorted(0, 0, size-1, computeRedLevel(size), it, str, defaultVal);
}

/**
 * 計算紅黑樹的高度
 */
private static int computeRedLevel(int sz) {
  int level = 0;
  for (int m = sz - 1; m >= 0; m = m / 2 - 1)
    level++;
  return level;
}

/**
 * 根據傳入的SortedMap構建TreeMap對象實現
 * 
 * @param level 樹的高度,初始值爲0
 * @param lo 子樹的第一個元素的索引,初始值爲0
 * @param hi 子樹的最後一個元素的索引,初始值爲size-1.
 * @param redLevel 哪些節點應該是紅色的節點. 它必須和computeRedLevel方法計算出來的一樣
 */
private final Entry<K,V> buildFromSorted(int level, int lo, int hi, int redLevel, Iterator<?> it, java.io.ObjectInputStream str, V defaultVal) throws java.io.IOException, ClassNotFoundException {
    if (hi < lo) return null;

    int mid = (lo + hi) >>> 1;

    Entry<K,V> left  = null;
    if (lo < mid)
        left = buildFromSorted(level+1, lo, mid - 1, redLevel,
                               it, str, defaultVal);

    K key;
    V value;
    if (it != null) {
        if (defaultVal==null) {
            Map.Entry<?,?> entry = (Map.Entry<?,?>)it.next();
            key = (K)entry.getKey();
            value = (V)entry.getValue();
        } else {
            key = (K)it.next();
            value = defaultVal;
        }
    } else { // use stream
        key = (K) str.readObject();
        value = (defaultVal != null ? defaultVal : (V) str.readObject());
    }

    Entry<K,V> middle =  new Entry<>(key, value, null);

    // color nodes in non-full bottommost level red
    if (level == redLevel)
        middle.color = RED;

    if (left != null) {
        middle.left = left;
        left.parent = middle;
    }

    if (mid < hi) {
        Entry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel,
                                           it, str, defaultVal);
        middle.right = right;
        right.parent = middle;
    }

    return middle;
}

/**
 * 在父類AbstractMap中的putAll()方法中,循環調用put(K key, V value)方法添加元素
 */
public void putAll(Map<? extends K, ? extends V> m) {
  // for循環調用put(key,value)方法來添加元素
  for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
    put(e.getKey(), e.getValue());
}

4、remove(Object key)

/**
 * 根據key來刪除Entry元素
 */
public V remove(Object key) {
  // 根據key來獲取Entry元素
  Entry<K,V> p = getEntry(key);
  
  // 當Entry元素不存在時,返回null
  if (p == null)
    return null;

  V oldValue = p.value;
  
  // 根據Entry來刪除Entry元素
  deleteEntry(p);
  
  // 返回刪除之前的value值
  return oldValue;
}

/**
 * 根據key來獲取Entry元素
 */
final Entry<K,V> getEntry(Object key) {
  if (comparator != null)
    return getEntryUsingComparator(key);
  // 下面的代碼爲根據key實現Comparable接口重寫compareTo方法來比較key元素的方式
  if (key == null)
    throw new NullPointerException();
  Comparable<? super K> k = (Comparable<? super K>) key;
  Entry<K,V> p = root;
  while (p != null) {
    // 這裏cmp爲傳入的key與節點元素中的key根據key中重寫的compareTo方法所比較的大小
    int cmp = k.compareTo(p.key);
    // 根據cmp的大小來判斷遍歷左子樹還是右子樹
    if (cmp < 0)
      p = p.left;
    else if (cmp > 0)
      p = p.right;
    else
      return p;
  }
  return null;
}

/**
 * 刪除Entry元素,並平衡紅黑樹
 */
private void deleteEntry(Entry<K,V> p) {
  modCount++;
  size--;

  // If strictly internal, copy successor's element to p and then make p
  // point to successor.
  if (p.left != null && p.right != null) {
    Entry<K,V> s = successor(p);
    p.key = s.key;
    p.value = s.value;
    p = s;
  } // p has 2 children

  // Start fixup at replacement node, if it exists.
  Entry<K,V> replacement = (p.left != null ? p.left : p.right);

  if (replacement != null) {
    // Link replacement to parent
    replacement.parent = p.parent;
    if (p.parent == null)
      root = replacement;
    else if (p == p.parent.left)
      p.parent.left  = replacement;
    else
      p.parent.right = replacement;

    // Null out links so they are OK to use by fixAfterDeletion.
    p.left = p.right = p.parent = null;

    // Fix replacement
    if (p.color == BLACK)
      fixAfterDeletion(replacement);
  } else if (p.parent == null) { // return if we are the only node.
    root = null;
  } else { //  No children. Use self as phantom replacement and unlink.
    if (p.color == BLACK)
      fixAfterDeletion(p);

    if (p.parent != null) {
      if (p == p.parent.left)
        p.parent.left = null;
      else if (p == p.parent.right)
        p.parent.right = null;
      p.parent = null;
    }
  }
}

5、remove(Object key, Object value)

/**
 * 根據key和value來刪除元素,該方法爲集合頂級接口Map中定義的接口默認實現方法
 */
default boolean remove(Object key, Object value) {
  Object curValue = get(key);
  
  // 判斷傳入的value值和根據key獲取的value值是否相等 || root紅黑樹中是否包含該key
  if (!Objects.equals(curValue, value) || (curValue == null && !containsKey(key))) {
    return false;
  }
  
  // 根據key來刪除Entry元素
  remove(key);
  
  return true;
}

/**
 * 從root紅黑樹中獲取Entry元素
 */
public V get(Object key) {
  Entry<K,V> p = getEntry(key);
  return (p==null ? null : p.value);
}

/**
 * 判斷root紅黑樹中是否包含該key
 */
public boolean containsKey(Object key) {
  return getEntry(key) != null;
}

6、size()

/**
 * 返回紅黑樹實際的元素個數
 */
public int size() {
    return size;
}

7、clear()

/**
 * 將root根據置爲null,同時size爲0
 */
public void clear() {
  modCount++;
  size = 0;
  root = null;
}

8、comparator()

/**
 * 返回比較器實例
 */
public Comparator<? super K> comparator() {
  return comparator;
}

9、equals(Object o)

/**
 * 調用的是父類AbstractMap中的equals(Object o)方法,用於比較當前TreeMap和傳入的Map對象中元素是否完全一樣
 */
public boolean equals(Object o) {
  // 如果是當前對象,直接返回true
  if (o == this)
    return true;
	// 如果不是Map對象,直接返回false
  if (!(o instanceof Map))
    return false;
  Map<?,?> m = (Map<?,?>) o;
  // 如果傳入的Map對象的size和當前TreeMap的size不一樣,直接返回false
  if (m.size() != size())
    return false;

  try {
    // 迭代器遍歷當前TreeMap集合
    Iterator<Entry<K,V>> i = entrySet().iterator();
    while (i.hasNext()) {
      Entry<K,V> e = i.next();
      K key = e.getKey();
      V value = e.getValue();
      
      // 當value爲null時
      if (value == null) {
        // 當!(m中該key下的value爲null並且包含此key時)
        if (!(m.get(key)==null && m.containsKey(key)))
          return false;
      }
      // 當value不爲null時
      else {
        // 當value不和傳入Map對象的value一致時
        if (!value.equals(m.get(key)))
          return false;
      }
    }
  } catch (ClassCastException unused) {
    return false;
  } catch (NullPointerException unused) {
    return false;
  }

  return true;
}

10、entrySet()

/**
 * 返回一個非空的EntrySet對象
 */
public Set<Map.Entry<K,V>> entrySet() {
  EntrySet es = entrySet;
  return (es != null) ? es : (entrySet = new EntrySet());
}

11、keySet()

/**
 * 返回一個非空的key的Set對象
 */
public Set<K> keySet() {
  return navigableKeySet();
}

/**
 * 返回一個非空的key的Set對象實現
 */
public NavigableSet<K> navigableKeySet() {
  KeySet<K> nks = navigableKeySet;
  return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this));
}

12、values()

/**
 * 返回一個非空的value的Collection對象
 */
public Collection<V> values() {
  Collection<V> vs = values;
  if (vs == null) {
    vs = new Values();
    values = vs;
  }
  return vs;
}

13、getFirstEntry()

/**
 * 獲取第一個Entry元素
 */
final Entry<K,V> getFirstEntry() {
  Entry<K,V> p = root;
  if (p != null)
    while (p.left != null)
      p = p.left;
  return p;
}

14、getLastEntry()

/**
 * 獲取最後一個Entry元素
 */
final Entry<K,V> getLastEntry() {
  Entry<K,V> p = root;
  if (p != null)
    while (p.right != null)
      p = p.right;
  return p;
}

15、firstKey()

/**
 * 獲取第一個Entry元素的key
 */
public K firstKey() {
  return key(getFirstEntry());
}

/**
 * 獲取Entry元素的key
 */
static <K> K key(Entry<K,?> e) {
  if (e==null)
    throw new NoSuchElementException();
  return e.key;
}

16、lastKey()

/**
 * 獲取最後一個Entry元素
 */
public K lastKey() {
  return key(getLastEntry());
}

/**
 * 獲取Entry元素的key
 */
static <K> K key(Entry<K,?> e) {
  if (e==null)
    throw new NoSuchElementException();
  return e.key;
}

17、ceilingEntry(K key)

/**
 * 返回至少大於或等於指定key的Entry對象,如果不存在這樣的Entry對象,返回null
 */
public Map.Entry<K,V> ceilingEntry(K key) {
  return exportEntry(getCeilingEntry(key));
}

/**
 * 返回至少大於或等於指定key的Entry對象,如果不存在這樣的Entry對象,返回null的實現
 */
final Entry<K,V> getCeilingEntry(K key) {
  Entry<K,V> p = root;
  while (p != null) {
    
    // 比較兩個key的大小
    int cmp = compare(key, p.key);
    
    // cmp<0,遍歷p的左子樹
    if (cmp < 0) {
      if (p.left != null)
        p = p.left;
      else
        return p;
    }
    
    // cmp>0,遍歷p的右子樹
    else if (cmp > 0) {
      if (p.right != null) {
        p = p.right;
      }
      
      // 當前節點的key比指定的key要小,需要找比當前節點key要大的節點,即右子樹,但是右子樹爲null,則上一個節點(父節點>左子樹節點)就是需要的節點
      else {
        Entry<K,V> parent = p.parent;
        Entry<K,V> ch = p;
        while (parent != null && ch == parent.right) {
          ch = parent;
          parent = parent.parent;
        }
        return parent;
      }
    } else
      return p;
  }
  return null;
}

/**
 * 將TreeMap.Entry中的key、value值賦值到AbstractMap.SimpleImmutableEntry中的key、value中
 */
static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) {
  return (e == null) ? null :
  new AbstractMap.SimpleImmutableEntry<>(e);
}

18、ceilingKey(K key)

/**
 * 返回至少大於或等於指定key的key
 */
public K ceilingKey(K key) {
  return keyOrNull(getCeilingEntry(key));
}

/**
 * 如果不存在這樣的Entry對象,返回null
 */
static <K,V> K keyOrNull(TreeMap.Entry<K,V> e) {
  return (e == null) ? null : e.key;
}

19、floorEntry(K key)

/**
 * 返回至少小於或等於指定key的Entry對象,如果不存在這樣的Entry對象,返回null
 */
public Map.Entry<K,V> floorEntry(K key) {
  return exportEntry(getFloorEntry(key));
}

/**
 * 返回至少小於或等於指定key的Entry對象,如果不存在這樣的Entry對象,返回null的實現
 */
final Entry<K,V> getFloorEntry(K key) {
  Entry<K,V> p = root;
  while (p != null) {
    
    // 比較兩個key的大小
    int cmp = compare(key, p.key);
    
    // cmp>0,遍歷p的右子樹
    if (cmp > 0) {
      if (p.right != null)
        p = p.right;
      else
        return p;
    }
    
    // cmp<0,遍歷p的左子樹
    else if (cmp < 0) {
      if (p.left != null) {
        p = p.left;
      }
      
      // 當前節點的key比指定的key要大,需要找比當前節點key要小的節點,即左子樹,但是左子樹爲null,則上一個節點(父節點>左子樹節點)就是需要的節點
      else {
        Entry<K,V> parent = p.parent;
        Entry<K,V> ch = p;
        while (parent != null && ch == parent.left) {
          ch = parent;
          parent = parent.parent;
        }
        return parent;
      }
    } else
      return p;

  }
  return null;
}

/**
 * 將TreeMap.Entry中的key、value值賦值到AbstractMap.SimpleImmutableEntry中的key、value中
 */
static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) {
  return (e == null) ? null :
  new AbstractMap.SimpleImmutableEntry<>(e);
}

20、ceilingEntry(K key)

/**
 * 返回至少小於或等於指定key的key
 */
public K floorKey(K key) {
  return keyOrNull(getFloorEntry(key));
}

/**
 * 如果不存在這樣的Entry對象,返回null
 */
static <K,V> K keyOrNull(TreeMap.Entry<K,V> e) {
  return (e == null) ? null : e.key;
}

總結

  • TreeMap有兩種方式定義key的比較規則,優先使用指定的構造器進行比較key
    • key實現Comparable接口重寫compareTo方法
    • 通過構造方法指定構造器
  • JDK1.8的TreeMap底層是用紅黑樹來實現的
  • 執行put()、remove()方法都會對紅黑樹進行平衡
  • TreeMap是線程不安全的,內部使用fast-fail機制當在使用HashMap中出現了線程安全問題時,將會拋出ConcurrentModificationException來提交你,避免你繼續錯下去
  • TreeMap中的元素都可以看做是一個Entry對象,每一個Entry對象都是紅黑樹中的一個節點,Entry對象主要包含六個成員變量
    • key:TreeMap的key
    • value:TreeMap的value
    • left:指向當前節點的左子樹
    • right:指向當前節點的右子樹
    • parent:指向當前節點的父節點
    • color:表示當前節點的顏色
  • keySet()、values()、entrySet()方法返回的都是空的內部實現類,該內部類在返回的時候內部並沒有元素,同時HashMap在put()的時候也並未特意將元素添加到內部類中,它是在迭代器遍歷的時候遍歷table數組中的Entry元素,也可以使用foreach遍歷(底層也是使用迭代器遍歷),set集合和collection集合中並未提供get()方法,所以不能使用普通for循環來遍歷
發佈了100 篇原創文章 · 獲贊 38 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章