TreeHashMap
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
/**
* Make a new cell with given key, value, and parent, and with
* {@code null} child links, and BLACK color.
*/
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) { //根节点为null
compare(key, key)
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
cmp = cpr.compare(key, t.key)
if (cmp < 0) //负数小于,在左边找
t = t.left
else if (cmp > 0) //正数大于,在右边找
t = t.right
else //相等,更新值
return t.setValue(value)
} while (t != null)
}
else { //没有自定义比较器,用key的比较方式
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)
}
//遍历完都没有找到,新建节点
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
}
compare
,用key
的比较方式进行比较,或者用传入的比较方式
final int compare(Object k1, Object k2) {
return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
: comparator.compare((K)k1, (K)k2);
}
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) {
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;
}
remove
public V remove(Object key) {
//查找
Entry<K,V> p = getEntry(key)
if (p == null)
return null
V oldValue = p.value
deleteEntry(p)
return oldValue
}
private void deleteEntry(Entry<K,V> p) {
//维护长度
modCount++
size--
// If strictly internal, copy successor's element to p and then make p
// point to successor.
//连接当前节点的父节点和中序遍历继任者,并赋值
if (p.left != null && p.right != null) { //叶子节点
Entry<K,V> s = successor(p)
p.key = s.key
p.value = s.value
p = s
} // p has 2 children
// Start fixup at replacement node, if it exists.
//待连接的节点,优先左子树
Entry<K,V> replacement = (p.left != null ? p.left : p.right)
if (replacement != null) {
replacement.parent = p.parent
if (p.parent == null) //删除的是根节点
root = replacement
else if (p == p.parent.left) //被删除的是左节点
p.parent.left = replacement
else
p.parent.right = replacement
// Null out links so they are OK to use by fixAfterDeletion.
//帮助gc
p.left = p.right = p.parent = null
// Fix replacement
//红黑树处理
if (p.color == BLACK)
fixAfterDeletion(replacement)
} else if (p.parent == null) { // return if we are the only node.
root = null
} else { // No children. Use self as phantom replacement and unlink.
//没有孩子节点,把本身删除
if (p.color == BLACK)
fixAfterDeletion(p)
if (p.parent != null) {
if (p == p.parent.left)
p.parent.left = null
else if (p == p.parent.right)
p.parent.right = null
p.parent = null
}
}
}
static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {
if (t == null)
return null
//核心思想,找中序遍历的的继任者
else if (t.right != null) { //优先考虑右子树的最左节点
Entry<K,V> p = t.right
while (p.left != null)
p = p.left
return p
} else { //找父节点的右子树
Entry<K,V> p = t.parent
Entry<K,V> ch = t
while (p != null && ch == p.right) {
ch = p
p = p.parent
}
return p
}
}
higherKey
getLowerEntry
过程镜像对称
- 找
大于 key 的节点
public K higherKey(K key) {
return keyOrNull(getHigherEntry(key));
}
final Entry<K,V> getHigherEntry(K key) {
Entry<K,V> p = root
while (p != null) {
int cmp = compare(key, p.key)
if (cmp < 0) { key < p.key
if (p.left != null) //左边还有,就在左边找
p = p.left
else //没有直接返回
return p
} else { // >=
if (p.right != null) { //当前节点有右子节点,那么往下找
p = p.right
} else { //没有,则找中序遍历的继任节点,且此时找到的节点一定比key大
//原因是,由上往下找,已经找到了parent.right 不存在
//key一定比parent.parent.key 小
Entry<K,V> parent = p.parent
Entry<K,V> ch = p
while (parent != null && ch == parent.right) {
ch = parent
parent = parent.parent
}
return parent
}
}
}
return null
}
ceilingKey
getFloorEntry
对称
- 返回一个
大于等于 key 的节点
public K ceilingKey(K key) {
return keyOrNull(getCeilingEntry(key));
}
final Entry<K,V> getCeilingEntry(K key) {
Entry<K,V> p = root
while (p != null) {
int cmp = compare(key, p.key)
if (cmp < 0) {
if (p.left != null)
p = p.left
else
return p
} else if (cmp > 0) {
if (p.right != null) {
p = p.right
} else {
Entry<K,V> parent = p.parent
Entry<K,V> ch = p
while (parent != null && ch == parent.right) {
ch = parent
parent = parent.parent
}
return parent
}
} else //相等可以返回
return p
}
return null
}
lastKey
public K lastKey() {
return key(getLastEntry());
}
final Entry<K,V> getLastEntry() {
Entry<K,V> p = root
if (p != null)
while (p.right != null)
p = p.right
return p
}
firstKey
public K firstKey() {
return key(getFirstEntry());
}
final Entry<K,V> getFirstEntry() {
Entry<K,V> p = root
if (p != null)
while (p.left != null)
p = p.left
return p
}
小结
- 维护
二叉搜索平衡树/红黑树
的结构
- 大小顺序逻辑上的是通过
中序遍历
实现的