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的看法,望多指点。

TreeMap源码分析——深入分析(基于JDK1.6)的更多相关文章

  1. java基础系列之ConcurrentHashMap源码分析(基于jdk1.8)

    1.前提 在阅读这篇博客之前,希望你对HashMap已经是有所理解的,否则可以参考这篇博客: jdk1.8源码分析-hashMap:另外你对java的cas操作也是有一定了解的,因为在这个类中大量使用 ...

  2. 源码分析系列1:HashMap源码分析(基于JDK1.8)

    1.HashMap的底层实现图示 如上图所示: HashMap底层是由  数组+(链表)+(红黑树) 组成,每个存储在HashMap中的键值对都存放在一个Node节点之中,其中包含了Key-Value ...

  3. HashMap源码分析(基于JDK1.6)

      在Java集合类中最常用的除了ArrayList外,就是HashMap了.本文尽自己所能,尽量详细的解释HashMap的源码.一山还有一山高,有不足之处请之处,定感谢指定并及时修正. 在看Hash ...

  4. ConcurrentHashMap 源码分析,基于JDK1.8

    1:几个重要的成员变量: private static final int MAXIMUM_CAPACITY = 1 << 30; //map 容器的最大容量 private static ...

  5. ArrayList源码分析(基于JDK1.8)

    public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess ...

  6. Java集合之TreeMap源码分析

    一.概述 TreeMap是基于红黑树实现的.由于TreeMap实现了java.util.sortMap接口,集合中的映射关系是具有一定顺序的,该映射根据其键的自然顺序进行排序或者根据创建映射时提供的C ...

  7. 集合-TreeMap源码分析

    一.简介 TreeMap最早出现在JDK 1.2中,是 Java 集合框架中比较重要一个的实现.TreeMap 底层基于红黑树实现,可保证在log(n)时间复杂度内完成 containsKey.get ...

  8. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  9. TreeMap 源码分析

    简介 TreeMap最早出现在JDK 1.2中,是 Java 集合框架中比较重要一个的实现.TreeMap 底层基于红黑树实现,可保证在log(n)时间复杂度内完成 containsKey.get.p ...

  10. TreeMap源码分析,看了都说好

    概述 TreeMap也是Map接口的实现类,它最大的特点是迭代有序,默认是按照key值升序迭代(当然也可以设置成降序).在前面的文章中讲过LinkedHashMap也是迭代有序的,不过是按插入顺序或访 ...

随机推荐

  1. ROS 知识

    安装 Ref: ROS安装过程中如何解决 rosdep update 命令出现错误 https://jiayaoo3o.github.io/2020/06/23/%E8%AE%B0%E5%BD%95% ...

  2. EF Core报错“Format of the initialization string does not conform to specification starting at index 0.”

    问题分析: 今天在EF Core数据库迁移的过程中无意中发现此错误,我的项目仅仅复制黏贴了配置文件而已,自此发现是数据库配置文件json在作祟. 对比了下发现是.json文件没有被设置"复制 ...

  3. 如何发布一个Vue组件到Npm上?

    前端时间做了一个基于Vue的拼图验证组件,因为公司需要,就想着做完之后放到Npm上,方便使用 发布流程如下: 1. 创建一个Npm账号并进行邮箱确认(很重要) 2. 创建一个文件夹,然后 npm in ...

  4. [namespace hdk] 64位 bitset

    功能 已重载运算符 [](int) (右值,修改请使用 set() 方法) ~() +(bitset) +(unsigned long long) +=(bitset) +=(unsigned lon ...

  5. Java项目笔记(五)

    这里写目录标题 @Valid 失效 解析jwt 无法建立SSL连接 windows下打jar包,读取nacos 配置文件 异常 @Valid 失效 加入以下依赖 <dependency> ...

  6. js递归遍历树形结构数据,获取所有数组id集合

    function getAllIds(tree, result) { //遍历树 获取id数组 for (const i in tree) { result.push(tree[i].id); // ...

  7. 常见的mysql 函数 字符串函数

    1. concat (s1,s2,....sn) 字符串拼接,将 s1,s2,... sn 拼接成一个字符串 : 2. lower(str) 将字符串全部转换成小写 3. upper(str) 将字符 ...

  8. Android复习(五)设备兼容—>支持刘海屏

    支持刘海屏 刘海屏是指某些设备显示屏上的一个区域延伸到显示面,这样既能为用户提供全面屏体验,又能为设备正面的重要传感器留出空间.Android 在搭载 Android 9(API 级别 28)及更高版 ...

  9. Android复习(三)清单文件中的元素——> provider、receiver、service

    <provider> 语法:   <provider android:authorities="list" android:directBootAware=[&q ...

  10. 深入理解Java并发读写锁——ReentrantReadWriteLock

    ReentrantReadWriteLock使用场景 ReentrantReadWriteLock 是 Java 的一种读写锁,它允许多个读线程同时访问,但只允许一个写线程访问(会阻塞所有的读写线程) ...