很多地方都用到了的Entry的源码,实现了Map.Entry接口及红黑树的put方法实现
比如TreeMap的底层实现是基于的红黑树,其中每个节点就是Entry<K,V>:
static final class Entry<K,V> implements Map.Entry<K,V> { //key,val是存储的原始数据 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; } /** * 获取节点的key值 */ public K getKey() {return key;} /** * 获取节点的value值 */ public V getValue() {return value;} /** * 用新值替换当前值,并返回当前值 */ public V setValue(V value) { V oldValue = this.value; this.value = value; return oldValue; } public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry<?,?> e = (Map.Entry<?,?>)o; return valEquals(key,e.getKey()) && valEquals(value,e.getValue()); } public int hashCode() { int keyHash = (key==null ? 0 : key.hashCode()); int valueHash = (value==null ? 0 : value.hashCode()); return keyHash ^ valueHash; } public String toString() { return key + "=" + value; } }
红黑树的put()方法实现:
private void fixAfterInsertion(Entry<K,V> x) { //新插入的节点为红色节点 x.color = RED; //我们知道父节点为黑色时,并不需要进行树结构调整,只有当父节点为红色时,才需要调整 while (x != null && x != root && x.parent.color == RED) { //如果父节点是左节点,对应上表中情况1和情况2 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); 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; }