TreeMap有Values、EntrySet、KeySet、PrivateEntryIterator、EntryIterator、ValueIterator、KeyIterator、DescendingKeyIterator、NavigableSubMap、AscendingSubMap、DescendingSubMap、SubMap、Entry共十三个内部类。Entry是在TreeMap中用于表示树的节点的内部类,已经在《java源码分析之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(Entr