zoukankan      html  css  js  c++  java
  • TreeMap源码分析——深入分析(基于JDK1.6)

     TreeMap有Values、EntrySet、KeySet、PrivateEntryIterator、EntryIterator、ValueIterator、KeyIterator、DescendingKeyIterator、NavigableSubMap、AscendingSubMap、DescendingSubMap、SubMap、Entry共十三个内部类。Entry是在TreeMap中用于表示树的节点的内部类,已经在《TreeMap源码分析——基础分析》中分析过。下面逐一介绍上面的内部类以及TreeMap中提供的和内部类相关的方法。

         先看Values。

    复制代码
     1 // 从类的定义可以看出,Values是一个集合类
     2 class Values extends AbstractCollection<V> {
     3     // 提供集合类Values的迭代器
     4     public Iterator<V> iterator() {
     5         return new ValueIterator(getFirstEntry());
     6     }
     7     // 返回TreeMap中保存的节点数
     8     public int size() {
     9         return TreeMap.this.size();
    10     }
    11     // 判断TreeMap中是否存在Value为o的节点
    12     public boolean contains(Object o) {
    13         return TreeMap.this.containsValue(o);
    14     }
    15     // 删除一个对象
    16     public boolean remove(Object o) {
    17         // 遍历TreeMap
    18         for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e)) {
    19             // 寻找值相等的节点
    20             if (valEquals(e.getValue(), o)) {
    21                 // 删除找到的节点
    22                 deleteEntry(e);
    23                 return true;
    24             }
    25         }
    26         return false;
    27     }
    28     // 清空TreeMap
    29     public void clear() {
    30         TreeMap.this.clear();
    31     }
    32 }
    复制代码

         Values类实际上是一个代理,多数方法都是调用TreeMap的方法。在Values的iterator()方法中返回了一个ValuesIterator对象,下面来看和迭代器相关的内部类。PrivateEntryIterator是TreeMap中和迭代器相关的类的基础,以下是PrivateEntryIterator的内容。

    复制代码
     1 abstract class PrivateEntryIterator<T> implements Iterator<T> {
     2     // 指向next的引用
     3 Entry<K,V> next;
     4 // 保留对上一次返回节点的引用
     5     Entry<K,V> lastReturned;
     6     int expectedModCount;
     7     // 构造方法,lastReturned置空,next指向传入的节点
     8     PrivateEntryIterator(Entry<K,V> first) {
     9         expectedModCount = modCount;
    10         lastReturned = null;
    11         next = first;
    12     }
    13     // 判断是否还有下一个节点
    14     public final boolean hasNext() {
    15         return next != null;
    16     }
    17     // 返回下一个节点
    18     final Entry<K,V> nextEntry() {
    19         Entry<K,V> e = next;
    20         if (e == null)
    21             throw new NoSuchElementException();
    22         if (modCount != expectedModCount)
    23             throw new ConcurrentModificationException();
    24         // next移动到它的继承者
    25         next = successor(e);
    26         // 记录被返回的节点
    27         lastReturned = e;
    28         // 返回原先记录的next节点
    29         return e;
    30     }
    31     // 前一个节点
    32     final Entry<K,V> prevEntry() {
    33         Entry<K,V> e = next;
    34         if (e == null)
    35             throw new NoSuchElementException();
    36         if (modCount != expectedModCount)
    37             throw new ConcurrentModificationException();
    38         // 获取指定节点的“前任”(按遍历次序的前一个节点)
    39         next = predecessor(e);
    40         // 记录被返回的节点
    41         lastReturned = e;
    42         return e;
    43     }
    44     // 移除最近一次被返回的节点
    45     public void remove() {
    46         if (lastReturned == null)
    47             throw new IllegalStateException();
    48         if (modCount != expectedModCount)
    49             throw new ConcurrentModificationException();
    50         // deleted entries are replaced by their successors
    51         if (lastReturned.left != null && lastReturned.right != null)
    52             /* 如果被删除节点有两个孩子,删除节点e的时候e的引用会被修改为指向原节点的继承者,所以这里先保留next对lastReturned的引用,这样在删除节点后就能获取到继承者的引用,继而继续遍历树 */
    53             next = lastReturned;
    54         // 删除节点
    55         deleteEntry(lastReturned);
    56         expectedModCount = modCount;
    57         lastReturned = null;
    58     }
    59 }
    复制代码

         PrivateEntryIterator类的prevEntry()方法用到了predecessor(Entry<K,V> t)方法,下面对这个方法进行介绍。

         predecessor(Entry<K,V> t)方法返回传入节点的“前一个”节点,至于前一个节点是哪个节点,这和树的遍历次序相关。根据successor(Entry<K,V> t)和predecessor(Entry<K,V> t)方法可以推出TreeMap中树的遍历次序是中根遍历(左孩子-根-右孩子)。

    复制代码
     1 static <K,V> Entry<K,V> predecessor(Entry<K,V> t) {
     2     if (t == null)
     3         return null;
     4 else if (t.left != null) {
     5     // 获得左孩子
     6         Entry<K,V> p = t.left;
     7         // 对左孩子进行遍历,获取左孩子最右的子孙
     8         while (p.right != null)
     9             p = p.right;
    10         return p;
    11 } else {
    12     // 获取t的父节点
    13         Entry<K,V> p = t.parent;
    14         Entry<K,V> ch = t; 
    15 // 沿着右孩子向上查找继承者,直到根节点或找到节点ch是其父节点的右孩子的节点
    16         while (p != null && ch == p.left) {
    17             ch = p;
    18             p = p.parent;
    19         }
    20         return p;
    21     }
    22 }
    复制代码

         下面是TreeMap中其它和迭代器相关的内部类。

    复制代码
     1 // EntryIterator就是树节点的迭代器,和PrivateEntryIterator完全一样,因为提供的方法都直接的调用而来父类的方法。
     2 final class EntryIterator extends PrivateEntryIterator<Map.Entry<K,V>> {
     3     EntryIterator(Entry<K,V> first) {
     4         super(first);
     5     }
     6     public Map.Entry<K,V> next() {
     7         return nextEntry();
     8     }
     9 }
    10 /** Value的迭代器 */
    11 final class ValueIterator extends PrivateEntryIterator<V> {
    12     ValueIterator(Entry<K,V> first) {
    13         super(first);
    14 }
    15 // next()方法返回的是节点的value值
    16     public V next() {
    17         return nextEntry().value;
    18     }
    19 }
    20 /** Key迭代器 */
    21 final class KeyIterator extends PrivateEntryIterator<K> {
    22     KeyIterator(Entry<K,V> first) {
    23         super(first);
    24 }
    25 // next()方法返回的是节点的key
    26     public K next() {
    27         return nextEntry().key;
    28     }
    29 }
    30 /** 逆序的Key迭代器 */
    31 final class DescendingKeyIterator extends PrivateEntryIterator<K> {
    32     DescendingKeyIterator(Entry<K,V> first) {
    33         super(first);
    34 }
    35 // next()方法返回的是节点的“前任”(按照遍历次序的前一个节点)的key
    36     public K next() {
    37         return prevEntry().key;
    38     }
    39 }
    复制代码

         除了迭代器相关的内部类,TreeMap还有两个和Set相关的内部类,分别是EntrySet和KeySet。两个类分别表示节点的集合和键的集合。下面具体看这两个类的实现。

    复制代码
     1 // 继承自AbstractSet说明是一个Set
     2 class EntrySet extends AbstractSet<Map.Entry<K,V>> {
     3     // iterator()方法返回的是上面介绍过的EntryIterator对象
     4     public Iterator<Map.Entry<K,V>> iterator() {
     5         return new EntryIterator(getFirstEntry());
     6     }
     7     // 判断是否包含某个节点的方法
     8     public boolean contains(Object o) {
     9         if (!(o instanceof Map.Entry))
    10             return false;
    11         Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
    12         V value = entry.getValue();
    13         Entry<K,V> p = getEntry(entry.getKey());
    14         // 判断是否包含某个对象的标准是存在节点的key的与传入对象的key值,且该节点的value也与存入对象的value值相等
    15         return p != null && valEquals(p.getValue(), value);
    16     }
    17     // 删除一个对象
    18     public boolean remove(Object o) {
    19         if (!(o instanceof Map.Entry))
    20             return false;
    21         Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
    22         V value = entry.getValue();
    23         Entry<K,V> p = getEntry(entry.getKey());
    24         // 如果存在该对象,则进行删除操作并返回true
    25         if (p != null && valEquals(p.getValue(), value)) {
    26             deleteEntry(p);
    27             return true;
    28         }
    29         // 不存在直接返回false
    30         return false;
    31     }
    32     // size()返回的是TreeMap中包含的节点的数量
    33     public int size() {
    34         return TreeMap.this.size();
    35     }
    36     // clear()方法实际调用了TreeMap的clear()方法,和size()方法都是代理方法
    37     public void clear() {
    38         TreeMap.this.clear();
    39     }
    40 }
    复制代码
    复制代码
     1 // KeySet同样继承自AbstractSet。KeySet实现了NavigableSet接口,意味着是“可导航”的Set,包含更多的获取指定节点的方法
     2 static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> {
     3 private final NavigableMap<E, Object> m;
     4 // 构造方法
     5     KeySet(NavigableMap<E,Object> map) { m = map; }
     6     // 
     7     public Iterator<E> iterator() {
     8         if (m instanceof TreeMap)
     9             return ((TreeMap<E,Object>)m).keyIterator();
    10         else
    11             // 这里涉及到的NavigableSubMap将在后面介绍
    12             return (Iterator<E>)(((TreeMap.NavigableSubMap)m).keyIterator());
    13     }
    14 
    15     public Iterator<E> descendingIterator() {
    16         if (m instanceof TreeMap)
    17             return ((TreeMap<E,Object>)m).descendingKeyIterator();
    18         else
    19             return (Iterator<E>)(((TreeMap.NavigableSubMap)m).descendingKeyIterator());
    20     }
    21     // size()方法返回的是通过构造方法传入的map的大小
    22 public int size() { return m.size(); }
    23 // isEmpty()判断是否为空也是判断的传入的map是否为空
    24 public boolean isEmpty() { return m.isEmpty(); }
    25 // contains(Object o)方法判断传入map中是否包含这个key
    26     public boolean contains(Object o) { return m.containsKey(o); }
    27 public void clear() { m.clear(); }
    28 // 因为传入的map是NavigableMap,所以下面这几个方法都是代理方法,调用map中相应的方法
    29     public E lower(E e) { return m.lowerKey(e); }
    30     public E floor(E e) { return m.floorKey(e); }
    31     public E ceiling(E e) { return m.ceilingKey(e); }
    32     public E higher(E e) { return m.higherKey(e); }
    33     public E first() { return m.firstKey(); }
    34 public E last() { return m.lastKey(); }
    35 // 获取传入map的比较器
    36 public Comparator<? super E> comparator() { return m.comparator(); }
    37 // 获取map中第一个节点的key
    38     public E pollFirst() {
    39         Map.Entry<E,Object> e = m.pollFirstEntry();
    40         return e == null? null : e.getKey();
    41 }
    42 // 获取map中最后一个节点的key
    43     public E pollLast() {
    44         Map.Entry<E,Object> e = m.pollLastEntry();
    45         return e == null? null : e.getKey();
    46 }
    47 // 删除一个对象,实际上是删除map中以这个对象为key的一个节点
    48     public boolean remove(Object o) {
    49         int oldSize = size();
    50         m.remove(o);
    51         return size() != oldSize;
    52 }
    53 // 下面的方法都是通过NavigableMap和TreeSet实现的,NavigableMap将在下文介绍,TreeSet将另开博文介绍
    54     public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
    55                                       E toElement,   boolean toInclusive) {
    56         return new TreeSet<E>(m.subMap(fromElement, fromInclusive,
    57                                            toElement,   toInclusive));
    58     }
    59     public NavigableSet<E> headSet(E toElement, boolean inclusive) {
    60         return new TreeSet<E>(m.headMap(toElement, inclusive));
    61     }
    62     public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
    63         return new TreeSet<E>(m.tailMap(fromElement, inclusive));
    64     }
    65     public SortedSet<E> subSet(E fromElement, E toElement) {
    66         return subSet(fromElement, true, toElement, false);
    67     }
    68     public SortedSet<E> headSet(E toElement) {
    69         return headSet(toElement, false);
    70     }
    71     public SortedSet<E> tailSet(E fromElement) {
    72         return tailSet(fromElement, true);
    73     }
    74     public NavigableSet<E> descendingSet() {
    75         return new TreeSet(m.descendingMap());
    76     }
    77 }
    复制代码

         介绍完了两个和Set相关的内部类,现在还剩下四个和SubMap相关的内部类:NavigableSubMap、AscendingSubMap、DescendingSubMap、SubMap。

         首先看NavigableSubMap,它足足有400多行代码,相当的多,需要耐心啊。

    复制代码
    复制代码
      1 // NavigableSubMap是一个抽象类,继承了AbstractMap,实现了NavigableMap接口
      2 static abstract class NavigableSubMap<K,V> extends AbstractMap<K,V>
      3         implements NavigableMap<K,V>, java.io.Serializable {
      4     // 存储内容的Map
      5     final TreeMap<K,V> m;
      6     // lowKey、highKey
      7     final K lo, hi;
      8     // 标识map的边界是否是map的第一个节点和最后一个节点
      9     final boolean fromStart, toEnd;
     10     // 是否包含最低lo、最高位置hi
     11 final boolean loInclusive, hiInclusive;
     12 // 通过上面的三组变量可以组成两个三元组表示一个集合的两个端点
     13     // 构造方法
     14     NavigableSubMap(TreeMap<K,V> m,
     15                         boolean fromStart, K lo, boolean loInclusive,
     16                         boolean toEnd,     K hi, boolean hiInclusive) {
     17         if (!fromStart && !toEnd) {
     18             // lo>hi抛出异常
     19             if (m.compare(lo, hi) > 0)
     20                 throw new IllegalArgumentException("fromKey > toKey");
     21         } else {
     22             if (!fromStart) // type check
     23                 m.compare(lo, lo);
     24             if (!toEnd)
     25                 m.compare(hi, hi);
     26         }
     27 
     28         this.m = m;
     29         this.fromStart = fromStart;
     30         this.lo = lo;
     31         this.loInclusive = loInclusive;
     32         this.toEnd = toEnd;
     33         this.hi = hi;
     34         this.hiInclusive = hiInclusive;
     35     }
     36 
     37     // tooLow 判断传入的key是否太小
     38     final boolean tooLow(Object key) {
     39         // 如果fromStart为false,需要判断最低边界 
     40         if (!fromStart) {
     41             int c = m.compare(key, lo);
     42             // 如果key<lo或者相等但是map的边界不包含lo,那么key越界了,即小于最小值
     43             if (c < 0 || (c == 0 && !loInclusive))
     44                 return true;
     45         }
     46         // 默认返回false
     47         return false;
     48     }
     49     // 与上面的tooLow类似
     50     final boolean tooHigh(Object key) {
     51         if (!toEnd) {
     52             int c = m.compare(key, hi);
     53             if (c > 0 || (c == 0 && !hiInclusive))
     54                 return true;
     55         }
     56         return false;
     57     }
     58     // 判断是否在范围内,即满足最低最高限制,结合tooLow和tooHigh即可
     59     final boolean inRange(Object key) {
     60         return !tooLow(key) && !tooHigh(key);
     61     }
     62     // 是否在封闭的区间内
     63     final boolean inClosedRange(Object key) {
     64         return (fromStart || m.compare(key, lo) >= 0)
     65                 && (toEnd || m.compare(hi, key) >= 0);
     66     }
     67     // 判断是否是在一个区间内
     68     final boolean inRange(Object key, boolean inclusive) {
     69         return inclusive ? inRange(key) : inClosedRange(key);
     70     }
     71     // 获取绝对的最低的节点
     72 final TreeMap.Entry<K,V> absLowest() {
     73 /* 如果fromStart为true,获取第一个节点,否则根据loInclusive是否为true,即是否包含lo来决定获取Ceiling节点或Higher节点;getCeilingEntry意为获取指定key的节点或者比指定key大的最小节点,如果不存在则返回null;getHigherEntry意为获取比指定key大的最小节点,如果不存在,返回null */
     74     TreeMap.Entry<K,V> e =
     75                 (fromStart ?  m.getFirstEntry() :
     76                  (loInclusive ? m.getCeilingEntry(lo) :
     77                                 m.getHigherEntry(lo)));
     78         // 判断得到的节点是否为空或者key过大
     79         return (e == null || tooHigh(e.key)) ? null : e;
     80     }
     81     // 与absLowest类似
     82     final TreeMap.Entry<K,V> absHighest() {
     83     TreeMap.Entry<K,V> e =
     84                 (toEnd ?  m.getLastEntry() :
     85                  (hiInclusive ?  m.getFloorEntry(hi) :
     86                                  m.getLowerEntry(hi)));
     87         return (e == null || tooLow(e.key)) ? null : e;
     88     }
     89     // 寻找大于等于key的最小的节点
     90 final TreeMap.Entry<K,V> absCeiling(K key) {
     91     // 如果key太小,返回绝对的最小的节点
     92         if (tooLow(key))
     93             return absLowest();
     94         // 获取允许的key的极限节点(满足要求的最小的节点)
     95         TreeMap.Entry<K,V> e = m.getCeilingEntry(key);
     96         return (e == null || tooHigh(e.key)) ? null : e;
     97     }
     98     // 和absCeiling类似,只是获取的不包含相等的情况,而是寻找大于key的最小节点
     99     final TreeMap.Entry<K,V> absHigher(K key) {
    100         if (tooLow(key))
    101             return absLowest();
    102         TreeMap.Entry<K,V> e = m.getHigherEntry(key);
    103         return (e == null || tooHigh(e.key)) ? null : e;
    104     }
    105     // 获取绝对的小于等于key的节点
    106 final TreeMap.Entry<K,V> absFloor(K key) {
    107     // 指定的key超出了hi,直接返回绝对的允许的最大的节点
    108         if (tooHigh(key))
    109             return absHighest();
    110         /* getFloorEntry 获取的是指定key的节点,如果不存在这样的节点,就去获取比指定key小的最大的节点,如果这样的节点也不存在,返回null*/
    111         TreeMap.Entry<K,V> e = m.getFloorEntry(key);
    112         return (e == null || tooLow(e.key)) ? null : e;
    113     }
    114     // 与上面的absFloor类似,只是不包含等于的情况
    115     final TreeMap.Entry<K,V> absLower(K key) {
    116         if (tooHigh(key))
    117             return absHighest();
    118         TreeMap.Entry<K,V> e = m.getLowerEntry(key);
    119         return (e == null || tooLow(e.key)) ? null : e;
    120     }
    121 
    122     // 返回比最大的节点“还要大”的节点(Fence是栅栏、围栏的意思)
    123 final TreeMap.Entry<K,V> absHighFence() {
    124     /* 如果toEnd是true,那么“围在”它外面的是null,如果是false,根据hi是否被包含返回getHigherEntry或getCeilingEntry,这两个方法意思在上面的方法中说明过了 */
    125         return (toEnd ? null : (hiInclusive ?
    126                                     m.getHigherEntry(hi) :
    127                                     m.getCeilingEntry(hi)));
    128     }
    129 
    130     // 与absHighFence类似
    131     final TreeMap.Entry<K,V> absLowFence() {
    132             return (fromStart ? null : (loInclusive ?
    133                                         m.getLowerEntry(lo) :
    134                                         m.getFloorEntry(lo)));
    135     }
    136 
    137     abstract TreeMap.Entry<K,V> subLowest();
    138     abstract TreeMap.Entry<K,V> subHighest();
    139     abstract TreeMap.Entry<K,V> subCeiling(K key);
    140     abstract TreeMap.Entry<K,V> subHigher(K key);
    141     abstract TreeMap.Entry<K,V> subFloor(K key);
    142     abstract TreeMap.Entry<K,V> subLower(K key);
    143     abstract Iterator<K> keyIterator();
    144     abstract Iterator<K> descendingKeyIterator();
    145 
    146     // 如果fromStart、toEnd都是true,那么判断空、获取大小都是直接通过m,不然就必须使用entrySet()先获取节点集
    147     public boolean isEmpty() {
    148         return (fromStart && toEnd) ? m.isEmpty() : entrySet().isEmpty();
    149     }
    150 
    151     public int size() {
    152         return (fromStart && toEnd) ? m.size() : entrySet().size();
    153     }
    154     // 判断是否存在key先判断范围,在通过TreeMap的containKey方法来判断
    155     public final boolean containsKey(Object key) {
    156         return inRange(key) && m.containsKey(key);
    157     }
    158     // 添加节点
    159 public final V put(K key, V value) {
    160     // 判断要添加的key是否在范围内
    161         if (!inRange(key))
    162             throw new IllegalArgumentException("key out of range");
    163         return m.put(key, value);
    164     }
    165     public final V get(Object key) {
    166         return !inRange(key)? null :  m.get(key);
    167     }
    168     public final V remove(Object key) {
    169         return !inRange(key)? null  : m.remove(key);
    170 }
    171 public final Map.Entry<K,V> ceilingEntry(K key) {
    172         /* exportEntry(TreeMap.Entry<K,V> e)方法返回的是Map.Entry<K,V>对象,它的Key 和Value和传入的节点的Key 和Value相同 */
    173         return exportEntry(subCeiling(key));
    174     }
    175 public final K ceilingKey(K key) {
    176         // keyOrNull根据传入的节点是否为null返回null或节点的key(相当于提供了一个null安全的获取key的方法)
    177         return keyOrNull(subCeiling(key));
    178     }
    179     public final Map.Entry<K,V> higherEntry(K key) {
    180         return exportEntry(subHigher(key));
    181     }
    182     public final K higherKey(K key) {
    183        return keyOrNull(subHigher(key));
    184     }
    185     public final Map.Entry<K,V> floorEntry(K key) {
    186         return exportEntry(subFloor(key));
    187     }
    188     public final K floorKey(K key) {
    189         return keyOrNull(subFloor(key));
    190     }
    191     public final Map.Entry<K,V> lowerEntry(K key) {
    192         return exportEntry(subLower(key));
    193     }
    194     public final K lowerKey(K key) {
    195         return keyOrNull(subLower(key));
    196     }
    197     public final K firstKey() {
    198         return key(subLowest());
    199     }
    200     public final K lastKey() {
    201         return key(subHighest());
    202     }
    203     public final Map.Entry<K,V> firstEntry() {
    204         return exportEntry(subLowest());
    205     }
    206     public final Map.Entry<K,V> lastEntry() {
    207         return exportEntry(subHighest());
    208     }
    209     // 返回并删除第一个节点
    210     public final Map.Entry<K,V> pollFirstEntry() {
    211     TreeMap.Entry<K,V> e = subLowest();
    212         Map.Entry<K,V> result = exportEntry(e);
    213         if (e != null)
    214             m.deleteEntry(e);
    215         return result;
    216     }
    217     // 返回并删除最后一个节点
    218     public final Map.Entry<K,V> pollLastEntry() {
    219     TreeMap.Entry<K,V> e = subHighest();
    220         Map.Entry<K,V> result = exportEntry(e);
    221         if (e != null)
    222             m.deleteEntry(e);
    223         return result;
    224     }
    225 
    226     // 这些都是视图
    227     transient NavigableMap<K,V> descendingMapView = null;
    228     transient EntrySetView entrySetView = null;
    229     transient KeySet<K> navigableKeySetView = null;
    230     // 返回TreeMap的KeySet
    231     public final NavigableSet<K> navigableKeySet() {
    232         KeySet<K> nksv = navigableKeySetView;
    233         return (nksv != null) ? nksv :
    234             (navigableKeySetView = new TreeMap.KeySet(this));
    235     }
    236     public final Set<K> keySet() {
    237         return navigableKeySet();
    238     }
    239     // 逆序的KeySet
    240     public NavigableSet<K> descendingKeySet() {
    241         return descendingMap().navigableKeySet();
    242     }
    243     // 返回一个子Map
    244     public final SortedMap<K,V> subMap(K fromKey, K toKey) {
    245         return subMap(fromKey, true, toKey, false);
    246     }
    247     // 下面这几个方法会在后面给出分析
    248     public final SortedMap<K,V> headMap(K toKey) {
    249         return headMap(toKey, false);
    250     }
    251     public final SortedMap<K,V> tailMap(K fromKey) {
    252         return tailMap(fromKey, true);
    253     }
    254 
    255     // 视图类
    256     abstract class EntrySetView extends AbstractSet<Map.Entry<K,V>> {
    257         private transient int size = -1, sizeModCount;
    258         // 返回子Map的大小
    259         public int size() {
    260             // 如果fromStart和toEnd都是true,返回的是m的size
    261             if (fromStart && toEnd)
    262                 return m.size();
    263             // size=-1或标记size不同,重新计算一次size
    264             if (size == -1 || sizeModCount != m.modCount) {
    265                 sizeModCount = m.modCount;
    266                 size = 0;
    267                 Iterator i = iterator();
    268                 while (i.hasNext()) {
    269                     size++;
    270                     i.next();
    271                 }
    272             }
    273             return size;
    274         }
    275         // 判断EntrySet是否为空
    276         public boolean isEmpty() {
    277             TreeMap.Entry<K,V> n = absLowest();
    278             return n == null || tooHigh(n.key);
    279         }
    280         // 判断是否包含某个对象
    281         public boolean contains(Object o) {
    282             if (!(o instanceof Map.Entry))
    283                 return false;
    284             Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
    285             K key = entry.getKey();
    286             // key不在范围内,返回false
    287             if (!inRange(key))
    288                 return false;
    289             // 判断是否有键和值如传入节点的键和值相等的节点
    290             TreeMap.Entry node = m.getEntry(key);
    291             return node != null &&
    292                 valEquals(node.getValue(), entry.getValue());
    293         }
    294         // 移除一个节点
    295         public boolean remove(Object o) {
    296             if (!(o instanceof Map.Entry))
    297                 return false;
    298             Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
    299             K key = entry.getKey();
    300             if (!inRange(key))
    301                 return false;
    302             TreeMap.Entry<K,V> node = m.getEntry(key);
    303             // 找到节点并移除,返回true
    304             if (node!=null && valEquals(node.getValue(),entry.getValue())){
    305                 m.deleteEntry(node);
    306                 return true;
    307             }
    308             return false;
    309         }
    310     }
    311 
    312     //子类迭代器
    313     abstract class SubMapIterator<T> implements Iterator<T> {
    314         // 上一次被返回的节点
    315         TreeMap.Entry<K,V> lastReturned;
    316         // 下一个节点
    317         TreeMap.Entry<K,V> next;
    318         // “栅栏”key(如果是向大的方向遍历,不能访问key大于等于fenceKey的节点;如果是向小的方向遍历,不能访问key小于等于fenceKey的节点)
    319         final K fenceKey;
    320         int expectedModCount;
    321         // 构造方法
    322         SubMapIterator(TreeMap.Entry<K,V> first,
    323                        TreeMap.Entry<K,V> fence) {
    324             expectedModCount = m.modCount;
    325             lastReturned = null;
    326             next = first;
    327             fenceKey = fence == null ? null : fence.key;
    328         }
    329         // 判断是否还有下一个节点
    330         public final boolean hasNext() {
    331             // 与普通的hasNext的判断不同的是这里必须判断next的key是否超出了fenceKey
    332             return next != null && next.key != fenceKey;
    333         }
    334         // 获得下一个节点的方法,比较容易理解
    335         final TreeMap.Entry<K,V> nextEntry() {
    336             TreeMap.Entry<K,V> e = next;
    337             if (e == null || e.key == fenceKey)
    338                 throw new NoSuchElementException();
    339             if (m.modCount != expectedModCount)
    340                 throw new ConcurrentModificationException();
    341             next = successor(e);
    342 lastReturned = e;
    343             return e;
    344         }
    345         // 另一种遍历方法,向前遍历
    346         final TreeMap.Entry<K,V> prevEntry() {
    347             TreeMap.Entry<K,V> e = next;
    348             if (e == null || e.key == fenceKey)
    349                 throw new NoSuchElementException();
    350             if (m.modCount != expectedModCount)
    351                 throw new ConcurrentModificationException();
    352             next = predecessor(e);
    353 lastReturned = e;
    354             return e;
    355         }
    356         // 删除节点后可以继续遍历剩余的节点,因为删除前用next保留了lastReturned节点,而这个节点在删除操作的过程中被替换成了它的继承者
    357         final void removeAscending() {
    358             if (lastReturned == null)
    359                 throw new IllegalStateException();
    360             if (m.modCount != expectedModCount)
    361                 throw new ConcurrentModificationException();
    362             if (lastReturned.left != null && lastReturned.right != null)
    363                 // next指向lastReturned所指向的节点,这个节点的内容在删除lastReturned的时候被改变了
    364                 next = lastReturned;
    365             m.deleteEntry(lastReturned);
    366             lastReturned = null;
    367             expectedModCount = m.modCount;
    368         }
    369         // 删除之后next指向的节点其实被删除了,不能继续迭代访问
    370         final void removeDescending() {
    371             if (lastReturned == null)
    372                 throw new IllegalStateException();
    373             if (m.modCount != expectedModCount)
    374                 throw new ConcurrentModificationException();
    375             m.deleteEntry(lastReturned);
    376             lastReturned = null;
    377             expectedModCount = m.modCount;
    378         }
    379 
    380     }
    381     //下面的几个内部类很简单,都是对SubMapIterator的调用或间接调用,不再解释
    382     final class SubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
    383         SubMapEntryIterator(TreeMap.Entry<K,V> first,
    384                                 TreeMap.Entry<K,V> fence) {
    385             super(first, fence);
    386         }
    387         public Map.Entry<K,V> next() {
    388             return nextEntry();
    389         }
    390         public void remove() {
    391             removeAscending();
    392         }
    393     }
    394 
    395     final class SubMapKeyIterator extends SubMapIterator<K> {
    396         SubMapKeyIterator(TreeMap.Entry<K,V> first,
    397                               TreeMap.Entry<K,V> fence) {
    398             super(first, fence);
    399         }
    400         public K next() {
    401             return nextEntry().key;
    402         }
    403         public void remove() {
    404             removeAscending();
    405         }
    406     }
    407 
    408     final class DescendingSubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
    409         DescendingSubMapEntryIterator(TreeMap.Entry<K,V> last,
    410                                           TreeMap.Entry<K,V> fence) {
    411             super(last, fence);
    412         }
    413 
    414         public Map.Entry<K,V> next() {
    415             return prevEntry();
    416         }
    417         public void remove() {
    418             removeDescending();
    419         }
    420     }
    421 
    422     final class DescendingSubMapKeyIterator extends SubMapIterator<K> {
    423         DescendingSubMapKeyIterator(TreeMap.Entry<K,V> last,
    424                                         TreeMap.Entry<K,V> fence) {
    425             super(last, fence);
    426         }
    427         public K next() {
    428             return prevEntry().key;
    429         }
    430         public void remove() {
    431             removeDescending();
    432         }
    433     }
    434 }
    复制代码
    复制代码

         NavigableSubMap类算是看了一遍,很复杂,自身是个内部类,它里面还包含了好几个类。理解它的代码需要部分TreeMap中的其他代码的深入理解,如涉及到的deleteEntry等方法(见《TreeMap源码分析——基础分析》)。

         下面看TreeMap的其他内部类,它们是NavigableSubMap的子类。

         AscendingSubMap

    复制代码
     1 // AscendingSubMap继承自NavigableSubMap
     2 static final class AscendingSubMap<K,V> extends NavigableSubMap<K,V> {
     3     private static final long serialVersionUID = 912986545866124060L;
     4     // 构造方法,直接调用父类构造方法
     5     AscendingSubMap(TreeMap<K,V> m,
     6                         boolean fromStart, K lo, boolean loInclusive,
     7                         boolean toEnd,     K hi, boolean hiInclusive) {
     8         super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
     9     }
    10     // 获得比较器
    11     public Comparator<? super K> comparator() {
    12         return m.comparator();
    13     }
    14     // “截取”子Map
    15     public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
    16                                         K toKey,   boolean toInclusive) {
    17         // 截取之前判断是否超出范围
    18         if (!inRange(fromKey, fromInclusive))
    19             throw new IllegalArgumentException("fromKey out of range");
    20         if (!inRange(toKey, toInclusive))
    21             throw new IllegalArgumentException("toKey out of range");
    22         return new AscendingSubMap(m,
    23                                        false, fromKey, fromInclusive,
    24                                        false, toKey,   toInclusive);
    25     }
    26     // “截取”子Map,headMap通过构造方法便可以实现
    27     public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
    28         if (!inRange(toKey, inclusive))
    29             throw new IllegalArgumentException("toKey out of range");
    30         return new AscendingSubMap(m,
    31                                        fromStart, lo,    loInclusive,
    32                                        false,     toKey, inclusive);
    33     }
    34     // 和headMap类似
    35     public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive){
    36         if (!inRange(fromKey, inclusive))
    37             throw new IllegalArgumentException("fromKey out of range");
    38         return new AscendingSubMap(m,
    39                                        false, fromKey, inclusive,
    40                                        toEnd, hi,      hiInclusive);
    41     }
    42     // 这个方法涉及到DescendingSubMap类的构造方法,在下面会介绍到
    43     public NavigableMap<K,V> descendingMap() {
    44         NavigableMap<K,V> mv = descendingMapView;
    45         return (mv != null) ? mv :
    46                 (descendingMapView =
    47                  new DescendingSubMap(m,
    48                                       fromStart, lo, loInclusive,
    49                                       toEnd,     hi, hiInclusive));
    50     }
    51     // 下面两个方法都是对上面提到过的构造方法的调用
    52     Iterator<K> keyIterator() {
    53         return new SubMapKeyIterator(absLowest(), absHighFence());
    54     }
    55     Iterator<K> descendingKeyIterator() {
    56         return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
    57 }
    58     // AscendingEntrySetView是一个视图类,重写了父类的iterator()方法,调用SubMapEntryIterator构造迭代器
    59     final class AscendingEntrySetView extends EntrySetView {
    60         public Iterator<Map.Entry<K,V>> iterator() {
    61             return new SubMapEntryIterator(absLowest(), absHighFence());
    62         }
    63     }
    64     // 获取节点集合的方法
    65     public Set<Map.Entry<K,V>> entrySet() {
    66         EntrySetView es = entrySetView;
    67         return (es != null) ? es : new AscendingEntrySetView();
    68     }
    69     // 父类中抽象方法的实现,都很简单
    70     TreeMap.Entry<K,V> subLowest()       { return absLowest(); }
    71     TreeMap.Entry<K,V> subHighest()      { return absHighest(); }
    72     TreeMap.Entry<K,V> subCeiling(K key) { return absCeiling(key); }
    73     TreeMap.Entry<K,V> subHigher(K key)  { return absHigher(key); }
    74     TreeMap.Entry<K,V> subFloor(K key)   { return absFloor(key); }
    75     TreeMap.Entry<K,V> subLower(K key)   { return absLower(key); }
    76 }
    复制代码

         DescendingSubMap

    复制代码
     1 // DescendingSubMap也继承自NavigableSubMap,和上面的AscendingSubMap对应
     2 static final class DescendingSubMap<K,V>  extends NavigableSubMap<K,V> {
     3     private static final long serialVersionUID = 912986545866120460L;
     4     DescendingSubMap(TreeMap<K,V> m,
     5                         boolean fromStart, K lo, boolean loInclusive,
     6                         boolean toEnd,     K hi, boolean hiInclusive) {
     7         super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
     8     }
     9     // 构造一个“相反”的比较器
    10     private final Comparator<? super K> reverseComparator =
    11         Collections.reverseOrder(m.comparator);
    12     // 获取的比较器是“相反”的比较器,比较结果会对调
    13     public Comparator<? super K> comparator() {
    14         return reverseComparator;
    15     }
    16     // subMap方法和AscendingSubMap类中类似
    17     public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
    18                                         K toKey,   boolean toInclusive) {
    19         if (!inRange(fromKey, fromInclusive))
    20             throw new IllegalArgumentException("fromKey out of range");
    21         if (!inRange(toKey, toInclusive))
    22             throw new IllegalArgumentException("toKey out of range");
    23         return new DescendingSubMap(m,
    24                                         false, toKey,   toInclusive,
    25                                         false, fromKey, fromInclusive);
    26     }
    27     // 与AscendingSubMap中其实是相反的
    28     public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
    29         if (!inRange(toKey, inclusive))
    30             throw new IllegalArgumentException("toKey out of range");
    31         // 因为DescendingSubMap表示的是逆序的map,所以其实是通过获取原序的尾部
    32         return new DescendingSubMap(m,
    33                                         false, toKey, inclusive,
    34                                         toEnd, hi,    hiInclusive);
    35     }
    36     // 与headMap对应,tailMap其实获取的是原序中的头部
    37     public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive){
    38         if (!inRange(fromKey, inclusive))
    39             throw new IllegalArgumentException("fromKey out of range");
    40         return new DescendingSubMap(m,
    41                                         fromStart, lo, loInclusive,
    42                                         false, fromKey, inclusive);
    43     }
    44     // 逆序的逆序其实是正序
    45     public NavigableMap<K,V> descendingMap() {
    46         NavigableMap<K,V> mv = descendingMapView;
    47         return (mv != null) ? mv :
    48                 (descendingMapView =
    49                  new AscendingSubMap(m,
    50                                      fromStart, lo, loInclusive,
    51                                      toEnd,     hi, hiInclusive));
    52     }
    53     // 剩余内容和AscendingSubMap很类似,就不说了
    54     Iterator<K> keyIterator() {
    55         return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
    56     }
    57     Iterator<K> descendingKeyIterator() {
    58         return new SubMapKeyIterator(absLowest(), absHighFence());
    59     }
    60     final class DescendingEntrySetView extends EntrySetView {
    61         public Iterator<Map.Entry<K,V>> iterator() {
    62             return new DescendingSubMapEntryIterator(absHighest(), absLowFence());
    63         }
    64     }
    65     public Set<Map.Entry<K,V>> entrySet() {
    66         EntrySetView es = entrySetView;
    67         return (es != null) ? es : new DescendingEntrySetView();
    68     }
    69     TreeMap.Entry<K,V> subLowest()       { return absHighest(); }
    70     TreeMap.Entry<K,V> subHighest()      { return absLowest(); }
    71     TreeMap.Entry<K,V> subCeiling(K key) { return absFloor(key); }
    72     TreeMap.Entry<K,V> subHigher(K key)  { return absLower(key); }
    73     TreeMap.Entry<K,V> subFloor(K key)   { return absCeiling(key); }
    74     TreeMap.Entry<K,V> subLower(K key)   { return absHigher(key); }
    75 }
    复制代码

         最后一个内部类是SubMap,它比较特别。这个类存在仅仅为了序列化兼容之前的版本不支持NavigableMap TreeMap。它被翻译成一个旧版本AscendingSubMap子映射到一个新版本。这个类是从来没有以其他方式使用。

    复制代码
     1 // SubMap 继承自AbstractMap;这个类存在仅仅为了序列化兼容之前的版本不支持NavigableMap TreeMap。它被翻译成一个旧版本AscendingSubMap子映射到一个新版本。这个类是从来没有以其他方式使用。
     2 private class SubMap extends AbstractMap<K,V>
     3     implements SortedMap<K,V>, java.io.Serializable {
     4     private static final long serialVersionUID = -6520786458950516097L;
     5     // 标识是否从map的开始到结尾都属于子map
     6     private boolean fromStart = false, toEnd = false;
     7     // 开始位置和结束位置的key
     8     private K fromKey, toKey;
     9     private Object readResolve() {
    10         return new AscendingSubMap(TreeMap.this,
    11                                        fromStart, fromKey, true,
    12                                        toEnd, toKey, false);
    13     }
    14     // 结合类定义和类的说明就明白为什么提供了这么多方法但是都不能用了
    15     public Set<Map.Entry<K,V>> entrySet() { throw new InternalError(); }
    16     public K lastKey() { throw new InternalError(); }
    17     public K firstKey() { throw new InternalError(); }
    18     public SortedMap<K,V> subMap(K fromKey, K toKey) { throw new InternalError(); }
    19     public SortedMap<K,V> headMap(K toKey) { throw new InternalError(); }
    20     public SortedMap<K,V> tailMap(K fromKey) { throw new InternalError(); }
    21     public Comparator<? super K> comparator() { throw new InternalError(); }
    22 }
    复制代码

         结合上面的内部类分析和《TreeMap源码分析——基础分析》,对TreeMap的实现应该有个大致轮廓。不过TreeMap的代码很长很复杂,不自己看一遍分析一边,很难想明白,很难理解进去。

         自己也理解的不是很好,如果有牛人有对TreeMap的看法,望多指点。

  • 相关阅读:
    概率面试题
    机器学习概率题总结(转载)
    筛素数以及判断数是否是素数
    腾讯2019正式批春笔试题
    推荐系统架构
    文本表示与匹配
    CTR预估经典模型总结
    spark运行原理
    leetcode 字符串动态规划总结
    无向图的邻接矩阵创建代码以及深度遍历广度遍历
  • 原文地址:https://www.cnblogs.com/daichangya/p/12959405.html
Copyright © 2011-2022 走看看