TreeMap

重要的属性
Comparator<? super K> comparator
比较器
Entry<K,V> root
根节点
int size
集合长度
特点
有序的集合,基于key进行排序
使用红黑树结构实现
Entry
static final class Entry<K,V> implements Map.Entry<K,V> {
K key;
V value;
Entry<K,V> left;
Entry<K,V> right;
Entry<K,V> parent;
// 默认节点为黑色
boolean color = BLACK;
Entry(K key, V value, Entry<K,V> parent) {
this.key = key;
this.value = value;
this.parent = parent;
}
}
put
//自底向上的插入
public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {//根节点为空
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节点
parent = t;
//key与t节点的key进行比较
cmp = cpr.compare(key, t.key);
if (cmp < 0) //key < t.key,则key在t的左侧;令t=t的左子节点,继续递归
t = t.left;
else if (cmp > 0) //key > t.key,则key在t的右侧;令t=t的右子节点,继续递归
t = t.right;
else
return t.setValue(value); //key = t.key,则说明有相同的key,更新value
} while (t != null); //从根节点一直遍历到叶子节点
}
else {
if (key == null)
throw new NullPointerException();
//key必须实现Comparable接口
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是第一次插入,且找到了parent;
* 创建Entry对象,根据cmp的比值来决定成为左或右子节点
*/
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;
}
private void fixAfterInsertion(Entry<K,V> x) {
x.color = RED; //当前节点设为红
while (x != null && x != root && x.parent.color == RED) { //父节点是红
if (parentOf(x) == leftOf(parentOf(parentOf(x)))) { //父节点是爷爷节点的左子节点
Entry<K,V> y = rightOf(parentOf(parentOf(x))); //获取父节点的兄弟节点
if (colorOf(y) == RED) { //若叔叔节点是红
setColor(parentOf(x), BLACK); //则父节点设为黑
setColor(y, BLACK); //叔叔节点设为黑
setColor(parentOf(parentOf(x)), RED); //爷爷节点设为红
x = parentOf(parentOf(x)); //继续向上递归
} else { //若叔叔节点是黑
if (x == rightOf(parentOf(x))) { //若当前节点是父节点的右子节点
x = parentOf(x); //x的引用执行父节点
rotateLeft(x); //左旋转
}
setColor(parentOf(x), BLACK);
setColor(parentOf(parentOf(x)), RED);
rotateRight(parentOf(parentOf(x)));
}
} else {
Entry<K,V> y = leftOf(parentOf(parentOf(x)));
if (colorOf(y) == RED) {
setColor(parentOf(x), BLACK);
setColor(y, BLACK);
setColor(parentOf(parentOf(x)), RED);
x = parentOf(parentOf(x));
} else {
if (x == leftOf(parentOf(x))) {
x = parentOf(x);
rotateRight(x);
}
setColor(parentOf(x), BLACK);
setColor(parentOf(parentOf(x)), RED);
rotateLeft(parentOf(parentOf(x)));
}
}
}
root.color = BLACK;
}
private void rotateLeft(Entry<K,V> p) {
if (p != null) {
Entry<K,V> r = p.right;
p.right = r.left;
if (r.left != null)
r.left.parent = p;
r.parent = p.parent;
if (p.parent == null)
root = r;
else if (p.parent.left == p)
p.parent.left = r;
else
p.parent.right = r;
r.left = p;
p.parent = r;
}
}
private void rotateRight(Entry<K,V> p) {
if (p != null) {
Entry<K,V> l = p.left;
p.left = l.right;
if (l.right != null) l.right.parent = p;
l.parent = p.parent;
if (p.parent == null)
root = l;
else if (p.parent.right == p)
p.parent.right = l;
else p.parent.left = l;
l.right = p;
p.parent = l;
}
}
Last updated