一、概述
TreeMap 是一个有序的key-value集合,它是通过红黑树实现的。
TreeMap 继承于AbstractMap,所以它是一个Map,即一个key-value集合。
TreeMap 实现了NavigableMap接口,意味着它支持一系列的导航方法。比如返回有序的key集合。
TreeMap 实现了Cloneable接口,意味着它能被克隆。
TreeMap 实现了java.io.Serializable接口,意味着它支持序列化。
SortedMap
扩展自Map接口,定义了有序的key-value键值对映射集合。根据key排序,使用Comparable或者Comparator进行排序。
特点:
- key需要支持排序。
submap:
- 1half-open they include their low* endpoint but not their high endpoint (where applicable)
- 1closed range which includes both endpoints
- 1open range which contains neither endpoint
定义API:
比较器相关:
- comparator():Comparator
视图相关:
- subMap(K, K): SortedMap<K, V>
- headMap(K): SortedMap<K, V>
- tailMap(K): SortedMap<K, V>
定位相关:
- firstKey(): K
- lastKey(): K
NavigableMap
扩展自SortedMap接口,添加搜索相关API,支持顺序遍历和反序遍历
定位相关API(Entry/key):
- lowerEntry(K): Entry<K, V>
- floorEntry(K): Entry<K, V>
- ceilingEntry(K): Entry<K, V>
- higherEntry(K): Entry<K, V>
- firstEntry(): Entry<K, V>
- lastEntry(): Entry<K, V>
action:
- pollFirstEntry(): Entry<K, V>
- pollLastEntry(): Entry<K, V>
反序列表:
- descendingMap():NavigableMap<K, V>
- descendingKeySet():NavigableSet<K>
视图相关:
- navigableKeySet(): NavigableSet<K>
- subMap(K, K):NavigableMap<K, V>
- headMap(K): NavigableMap<K, V>
- tailMap(K): NavigableMap<K, V>
注意点:
NavigableMap中视图相关方法与SortedMap中视图相关方法不同,NavigableMap中返回类型为NavigableMap,SortedMap中返回类型为SortedMap
二、数据结构
TreeMap是通过红黑树实现的,TreeMap存储的是key-value键值对,TreeMap的排序是基于对key的排序。
使用链式结构存储元素,只记录root节点。使用size保存元素数量。
private transient TreeMapEntry<K,V> root = null;
private transient int size = 0;
保存一个Comparator,同于key排序。
private final Comparator<? super K> comparator;
TreeMapEntry
实现了Map.Entry<K,V>接口,保存基本key、value信息。
持有父节点、左子节点、右子节点的引用。
记录本节点的颜色(红黑树需要)。
K key;
V value;
TreeMapEntry<K,V> left = null;
TreeMapEntry<K,V> right = null;
TreeMapEntry<K,V> parent;
boolean color = BLACK;
红黑树(R-B Tree)
R-B Tree,全称是Red-Black Tree,又称为“红黑树”。
基本操作
- 左旋
- 右旋
- 插入
- 插入修正
- 删除
- 删除修正
时间复杂度:基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n)
三、特点
- 有序,可使用Comparator进行排序,或者对key进行默认排序。
- Iterator是fail-fast的
- 非线程安全。可使用Collections.synchronizedSortedMap()
- 性能稳定。基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n)
- 对外Entry为snapshots,不可修改。
- 不支持key为null值,value可以为null。
四、实现原理
1.基本方法
构造函数
四个:空构造函数、Comparator构造函数、Map构造函数、SortedMap构造函数
SortedMap构造函数:获取SortedMap的Comparator,设置为自身的Comparator
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) {
}
}
基本操作
添加 - key不能为null,value不能为null,插入到红黑树中
删除 - getEntry(key),然后删除该节点
clear - 设置root为null,size为null
查询(见下面具体分类)
entry相关操作
查询:
getEntry:根据红黑树性质查找节点
final TreeMapEntry<K,V> getEntry(Object key) {
// Offload comparator-based version for sake of performance
if (comparator != null)
return getEntryUsingComparator(key);
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
TreeMapEntry<K,V> p = root;
while (p != null) {
int cmp = k.compareTo(p.key);
if (cmp < 0)
p = p.left;
else if (cmp > 0)
p = p.right;
else
return p;
}
return null;
}
firstEntry: 返回最left的节点
final TreeMapEntry<K,V> getFirstEntry() {
TreeMapEntry<K,V> p = root;
if (p != null)
while (p.left != null)
p = p.left;
return p;
}
lastEntry: 返回最right的节点
final TreeMapEntry<K,V> getLastEntry() {
TreeMapEntry<K,V> p = root;
if (p != null)
while (p.right != null)
p = p.right;
return p;
}
注意:
返回的entry并不是真实的元素,是新生的一个不可修改的entry,避免通过entry修改map结构
static <K,V> Map.Entry<K,V> exportEntry(TreeMapEntry<K,V> e) {
return (e == null) ? null :
new AbstractMap.SimpleImmutableEntry<>(e);
}
key相关操作
containsKey:使用Comparator比较key
final TreeMapEntry<K,V> getEntryUsingComparator(Object key) {
@SuppressWarnings("unchecked")
K k = (K) key;
Comparator<? super K> cpr = comparator;
if (cpr != null) {
TreeMapEntry<K,V> p = root;
while (p != null) {
int cmp = cpr.compare(k, p.key);
if (cmp < 0)
p = p.left;
else if (cmp > 0)
p = p.right;
else
return p;
}
}
return null;
}
value相关操作
containValue :使用了两个内部方法 successor(TreeMapEntry<K,V> t)和predecessor(TreeMapEntry<K,V> t),用于返回仅大于/小于当前entry的key的entry,通过这两个方法遍历map即根据key的顺序来便利map。
public boolean containsValue(Object value) {
for (TreeMapEntry<K,V> e = getFirstEntry(); e != null; e = successor(e))
if (valEquals(value, e.value))
return true;
return false;
}
2.访问方式
PrivateEntryIterator
实现Iterator类,持有next和lastReturned两个指针。
TreeMapEntry<K,V> next;
TreeMapEntry<K,V> lastReturned;
int expectedModCount;
支持前/后移动和查询、删除操作。
调用主类中的successor(e)和 predecessor(e)方法获取下一个/上一个entry。
EntryIterator
继承PrivateEntryIterator
next返回entry
KeyIterator
继承PrivateEntryIterator
next返回key
ValueIterator
继承PrivateEntryIterator
next返回value
DescendingKeyIterator
继承PrivateEntryIterator
next返回prevEntry
重写remove方法,删除前一个元素。
3.排序原理
默认排序,Comparable natural ordering of keys
Comparator排序
五、视图
支持四种视图,EntrySet、KeySet、Values和SubMap,SubMap又可分为顺序和逆序两种。
NavigableSubMap
继承AbstractMap,持有原NavigableMap的引用。记录lowKey、highKey或者直到Start、End,以及边缘值的包含关系。
final TreeMap<K,V> m;
final K lo, hi;
final boolean fromStart, toEnd;
final boolean loInclusive, hiInclusive;
API
- 支持大部分NavigableMap方法,通过调用原map实现。
- 支持继续生成subMap。(Abstract)方法。
- 包含自己的entrySet、keySet、values
- 包含自己的Iterator
子类AscendingSubMap和DescendingSubMap,分别表示顺序和逆序。
EntrySet
继承AbstractSet<Map.Entr<K,V>>
调用原Map方法实现,Iterator返回EntryIterator
KeySet
继承AbstractSet<Map.Entr<K,V>>,实现NavigableSet<E>接口。
调用原Map方法实现,Iterator返回KeyIterator/DescendingKeyIterator
Values
继承AbstractCollection<V>
调用原Map方法实现
六、性能
时间复杂度:基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n)
证明过程略。
网友评论