TreeMap是实现了排序功能的Map,如果不传入比较器,则按照key的自然顺序排序。
它的数据结构是完全基于红黑树
public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, java.io.Serializable
{
// 比较器
private final Comparator<? super K> comparator;
// 红黑树的根节点
private transient Entry<K,V> root;
// 节点数量
private transient int size = 0;
// 修改树结构的次数
private transient int modCount = 0;
}
// 构造函数
public TreeMap() {
comparator = null;
}
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
public TreeMap(Map<? extends K, ? extends V> m) {
comparator = null;
putAll(m);
}
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) {
}
}
// 放入元素
public V put(K key, V value) {
// 获取根节点
Entry<K,V> t = root;
// 如果根节点为null,则新建根节点root
if (t == null) {
// key的比较器,也可以用于类型检查和key为null的检查
// key(非基本类型)需要实现Comparable接口,否则抛ClassCastException
// 在自然排序情况下或者实现的比较器不允许null的情况下,key为null抛出NullPointerException
compare(key, key); // type (and possibly null) check
// 新建根节点
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator;
// 区分实现了比较器和没有实现比较器两条路径
// 实现了比较器
if (cpr != null) {
do {
// 从根节点开始遍历
parent = t;
// 利用比较器比较key的大小,小的往左儿子走,大的往右儿子走(红黑树特性(二叉查找树))
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
// 找到相同的key,则替换value值,返回旧的value
return t.setValue(value);
} while (t != null);
}
else {
// 没有实现比较器,key按照自然排序
// 保证key不为null,否则抛异常
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
do {
// 和上面一样遍历查找
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
// 上面的步骤都没有找到key相同的值,则插入一个新节点到红黑树
Entry<K,V> e = new Entry<>(key, value, parent);
// 利用上面查找的最后结果,看新节点插入到左儿子节点还是右儿子节点
if (cmp < 0)
parent.left = e;
else
parent.right = e;
// 插入之后修正红黑树
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
// get方法
public V get(Object key) {
Entry<K,V> p = getEntry(key);
return (p==null ? null : p.value);
}
final Entry<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;
Entry<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;
}
// 在比较器不为null的情况下,就用比较器去比较key,然后查找
final Entry<K,V> getEntryUsingComparator(Object key) {
@SuppressWarnings("unchecked")
K k = (K) key;
Comparator<? super K> cpr = comparator;
if (cpr != null) {
Entry<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;
}
// 获取树上的第一个Entry,即排序器下的key最小的entry,也即是树最左的节点
public Map.Entry<K,V> firstEntry() {
return exportEntry(getFirstEntry());
}
final Entry<K,V> getFirstEntry() {
Entry<K,V> p = root;
if (p != null)
while (p.left != null)
p = p.left;
return p;
}
// 把entry的key和value变成不可变的(final)
static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) {
return (e == null) ? null :
new AbstractMap.SimpleImmutableEntry<>(e);
}