终于通过不屑努力,把源码中的重要部分全都看完了,每一行代码都看明白了,还写了注释
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;public class MyHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V> {static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;static final int MAXIMUM_CAPACITY = 1 << 30;static final float DEFAULT_LOAD_FACTOR = 0.75f;static final int TREEIFY_THRESHOLD = 8;static final int UNTREEIFY_THRESHOLD = 6;static final int MIN_TREEIFY_CAPACITY = 64;static class Node<K, V> implements Map.Entry<K, V> {final int hash;final K key;V value;Node<K, V> next;Node(int hash, K key, V value, Node<K, V> next) {this.hash = hash;this.key = key;this.value = value;this.next = next;}@Overridepublic K getKey() {return key;}@Overridepublic V getValue() {return value;}@Overridepublic V setValue(V value) {V oldValue = this.value;this.value = value;return oldValue;}@Overridepublic boolean equals(Object o) {if (this == o)return true;if (o instanceof Map.Entry) {Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;if (Objects.equals(key, e.getKey()) && Objects.equals(value, e.getValue())) {return true;}}return false;}}static final int hash(Object key) {if (key == null)return 0;int hash = key.hashCode();hash = hash ^ (hash >>> 16);return hash;}static Class<?> comparableClassFor(Object x) {if (x instanceof Comparable) {Class<?> c;Type[] ts, as;Type t;ParameterizedType p;if ((c = x.getClass()) == String.class) return c;if ((ts = c.getGenericInterfaces()) != null) {for (int i = 0; i < ts.length; ++i) {if (((t = ts[i]) instanceof ParameterizedType) &&((p = (ParameterizedType) t).getRawType() ==Comparable.class) &&(as = p.getActualTypeArguments()) != null &&as.length == 1 && as[0] == c) return c;}}}return null;}static int compareComparables(Class<?> kc, Object k, Object x) {return (x == null || x.getClass() != kc ? 0 :((Comparable) k).compareTo(x));}static final int tableSizeFor(int cap) {int n = cap - 1;n |= n >>> 1;n |= n >>> 2;n |= n >>> 4;n |= n >>> 8;n |= n >>> 16;return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;}@Overridepublic Set<Entry<K, V>> entrySet() {return null;}transient Node<K, V>[] table;transient Set<Entry<K, V>> entrySet;transient int size;transient int modCount;int threshold;final float loadFactor;public MyHashMap(int initialCapacity, float loadFactor) {if (initialCapacity < 0)throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);if (initialCapacity > MAXIMUM_CAPACITY)initialCapacity = MAXIMUM_CAPACITY;if (loadFactor <= 0 || Float.isNaN(loadFactor)) {throw new IllegalArgumentException("Illegal load factor: " + loadFactor);}this.loadFactor = loadFactor;this.threshold = tableSizeFor(initialCapacity);}public MyHashMap(int initialCapacity) {this(initialCapacity, DEFAULT_LOAD_FACTOR);}public MyHashMap() {this.loadFactor = DEFAULT_LOAD_FACTOR; }public MyHashMap(Map<? extends K, ? extends V> m) {this.loadFactor = DEFAULT_LOAD_FACTOR;putMapEntries(m, false);}final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {int s = m.size();if (s > 0) {if (table == null) {float ft = ((float) s / loadFactor) + 1.0F;int t = MAXIMUM_CAPACITY;if (ft < (float) MAXIMUM_CAPACITY) {t = (int) ft;}if (t > threshold)threshold = tableSizeFor(t);} else if (s > threshold)resize();for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {K key = e.getKey();V value = e.getValue();putVal(hash(key), key, value, false, evict);}}}public int size() {return size;}public boolean isEmpty() {return size == 0;}public V get(Object key) {Node<K, V> e;return (e = getNode(hash(key), key)) == null ? null : e.value;}final Node<K, V> getNode(int hash, Object key) {Node<K, V>[] tab;Node<K, V> first, e;int n;K k;if ((tab = table) != null && (n = tab.length) > 0 &&(first = tab[(n - 1) & hash]) != null) {if (first.hash == hash && ((k = first.key) == key || (key != null && key.equals(k))))return first;if ((e = first.next) != null) {if (first instanceof TreeNode)return ((TreeNode<K, V>) first).getTreeNode(hash, key);do {if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))return e;} while ((e = e.next) != null);}}return null;}final Node<K, V>[] resize() {Node<K, V>[] oldTable = table;int oldCapacity = (oldTable == null) ? 0 : oldTable.length;int oldThreshold = threshold;int newCapacity = 0;int newThreshold = 0;if (oldCapacity > 0) {if (oldCapacity >= MAXIMUM_CAPACITY) {threshold = Integer.MAX_VALUE;return oldTable;} else {if (oldCapacity >= DEFAULT_INITIAL_CAPACITY &&(oldCapacity << 1) < MAXIMUM_CAPACITY) {newCapacity = oldCapacity << 1;newThreshold = oldThreshold << 1;}}} else if (oldThreshold > 0) {newCapacity = oldThreshold;} else {newCapacity = DEFAULT_INITIAL_CAPACITY;newThreshold = (int) (DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);}if (newThreshold == 0) {float ft = (float) newCapacity * loadFactor;newThreshold = (newCapacity < MAXIMUM_CAPACITY && ft < (float) MAXIMUM_CAPACITY ?(int) ft : Integer.MAX_VALUE);}threshold = newThreshold;Node<K, V>[] newTable = (Node<K, V>[]) new Node[newCapacity];table = newTable;if (oldTable != null) {for (int j = 0; j < oldCapacity; j++) {Node<K, V> e = oldTable[j];if (e == null)continue;oldTable[j] = null;if (e.next == null) {newTable[e.hash & (newCapacity - 1)] = e;} else if (e instanceof TreeNode) {((TreeNode<K, V>) e).split(this, newTable, j, oldCapacity);} else {Node<K, V> loHead = null, loTail = null;Node<K, V> hiHead = null, hiTail = null;Node<K, V> next;do {next = e.next;if ((e.hash & oldCapacity) == 0) {if (loTail == null)loHead = e;elseloTail.next = e;loTail = e;} else {if (hiTail == null)hiHead = e;elsehiTail.next = e;hiTail = e;}} while ((e = next) != null);if (loTail != null) {loTail.next = null;newTable[j] = loHead;}if (hiTail != null) {hiTail.next = null;newTable[j + oldCapacity] = hiHead;}}}}return newTable;}public V put(K key, V value) {return putVal(hash(key), key, value, false, true);}final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K, V>[] tab;Node<K, V> p;int len, index;if ((tab = table) == null || (len = tab.length) == 0)len = (tab = resize()).length;if ((p = tab[index = (len - 1) & hash]) == null)tab[index] = newNode(hash, key, value, null);else {Node<K, V> e;K k;if (p.hash == hash && compareKey(key, p.key))e = p;else if (p instanceof TreeNode)e = ((TreeNode<K, V>) p).putTreeVal(this, tab, hash, key, value);else {for (int binCount = 0; ; ++binCount) {if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);if (binCount >= TREEIFY_THRESHOLD - 1) treeifyBin(tab, hash);break;}if (e.hash == hash && compareKey(key, e.key))break;p = e;}}if (e != null) { V oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;
return oldValue;}}++modCount;if (++size > threshold)resize();return null;}final void treeifyBin(Node<K, V>[] tab, int hash) {int len, index;Node<K, V> e;if (tab == null || (len = tab.length) < MIN_TREEIFY_CAPACITY)resize();else if ((e = tab[index = (len - 1) & hash]) != null) {TreeNode<K, V> head = null, tail = null;do {TreeNode<K, V> p = replacementTreeNode(e, null);if (tail == null)head = p;else {p.prev = tail;tail.next = p;}tail = p;} while ((e = e.next) != null);if ((tab[index] = head) != null)head.treeify(tab);}}public void putAll(Map<? extends K, ? extends V> m) {putMapEntries(m, true);}final boolean compareKey(K k1, K k2) {return Objects.equals(k1, k2);}@Overridepublic V remove(Object key) {Node<K, V> e;e = removeNode(hash(key), key, null, false, true);if (e == null)return null;return e.value;}@Overridepublic boolean replace(K key, V oldValue, V newValue) {Node<K, V> e;V v;if ((e = getNode(hash(key), key)) != null &&((v = e.value) == oldValue || (v != null && v.equals(oldValue)))) {e.value = newValue;return true;}return false;}@Overridepublic V replace(K key, V value) {Node<K, V> e;if ((e = getNode(hash(key), key)) != null) {V oldValue = e.value;e.value = value;return oldValue;}return null;}final Node<K, V> removeNode(int hash, Object key, Object value,boolean matchValue, boolean movable) {Node<K, V>[] tab;Node<K, V> p;int n, index;if ((tab = table) != null && (n = tab.length) > 0 && (p = tab[index = (n - 1) & hash]) != null) {Node<K, V> node = null;Node<K, V> e;K k;V v;if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) {node = p;} else if ((e = p.next) != null) {if (p instanceof TreeNode) {node = ((TreeNode<K, V>) p).getTreeNode(hash, key);}else {do {if (e.hash == hash && compareKey(e.key, key)) {node = e;break;}p = e;} while ((e = e.next) != null);}}if (node != null && (!matchValue || (v = node.value) == value ||(value != null && value.equals(v)))) {if (node instanceof TreeNode) {((TreeNode<K, V>) node).removeTreeNode(this, tab, movable);} else if (node == p) {tab[index] = node.next;} else {p.next = node.next;}++modCount;--size;return node;}}return null;}public void clear() {Node<K, V>[] tab;modCount++;if ((tab = table) != null && size > 0) {size = 0;for (int i = 0; i < tab.length; ++i) {tab[i] = null;}}}public boolean containsValue(Object value) {Node<K, V>[] tab;V v;if ((tab = table) != null && size > 0) {for (int i = 0; i < tab.length; i++) {for (Node<K, V> e = tab[i]; e != null; e = e.next) {if ((v = e.value) == value || (value != null && value.equals(v))) {return true;}}}}return false;}@Overridepublic V getOrDefault(Object key, V defaultValue) {Node<K, V> e;return (e = getNode(hash(key), key)) == null ? defaultValue : e.value;}@Overridepublic V putIfAbsent(K key, V value) {return putVal(hash(key), key, value, true, true);}@Overridepublic V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {if (mappingFunction == null)throw new NullPointerException();int hash = hash(key);Node<K, V>[] tab;Node<K, V> first; int n, i; int binCount = 0;TreeNode<K, V> t = null; Node<K, V> old = null; if (size > threshold || (tab = table) == null || (n = tab.length) == 0) {n = (tab = resize()).length;}if ((first = tab[i = (n - 1) & hash]) != null) {if (first instanceof TreeNode) {old = (t = (TreeNode<K, V>) first).getTreeNode(hash, key);} else {Node<K, V> e = first;K k;do {if (e.hash == hash &&((k = e.key) == key) || (key != null && key.equals(k))) {old = e;break;}++binCount;} while ((e = e.next) != null);}V oldValue;if (old != null && (oldValue = old.value) != null) {return oldValue;}}V v = mappingFunction.apply(key);if (v == null) {return null;} else if (old != null) {old.value = v;return v;}else if (t != null) {t.putTreeVal(this, tab, hash, key, v);} else {tab[i] = newNode(hash, key, v, first);if (binCount >= TREEIFY_THRESHOLD - 1) {treeifyBin(tab, hash);}}++modCount;++size;return v;}TreeNode<K, V> replacementTreeNode(Node<K, V> p, Node<K, V> next) {return new TreeNode<>(p.hash, p.key, p.value, next);}static final class TreeNode<K, V> extends MyLinkedHashMap.Entry<K, V> {TreeNode<K, V> parent; TreeNode<K, V> left;TreeNode<K, V> right;TreeNode<K, V> prev; boolean red;TreeNode(int hash, K key, V val, Node<K, V> next) {super(hash, key, val, next);}final TreeNode<K, V> root() {TreeNode<K, V> p = this;while (p.parent != null) {p = p.parent;}return p;}final void treeify(Node<K, V>[] tab) {TreeNode<K, V> root = null;for (TreeNode<K, V> x = this, next; x != null; x = next) {next = (TreeNode<K, V>) x.next;x.left = x.right = null;if (root == null) {x.parent = null;x.red = false;root = x;} else {K k = x.key;int h = x.hash;Class<?> kc = null;TreeNode<K, V> p = root;while (true) {int dir;int ph = p.hash;K pk = p.key;if (h < ph) {dir = -1;} else if (h > ph) {dir = 1;} else if ((kc == null &&(kc = comparableClassFor(k)) == null) ||(dir = compareComparables(kc, k, pk)) == 0)dir = tieBreakOrder(k, pk);TreeNode<K, V> xp = p;if (dir <= 0) {p = p.left;} else {p = p.right;}if (p == null) {x.parent = xp;if (dir <= 0) {xp.left = x;} else {xp.right = x;}root = balanceInsertion(root, x);break;}}}}moveRootToFront(tab, root);}final Node<K, V> untreeify(MyHashMap<K, V> map) {Node<K, V> head = null, tail = null;Node<K, V> q = root();while (q != null) {Node<K, V> p = map.replacementNode(q, null);if (tail == null)head = p;elsetail.next = p;tail = p;q = q.next;}return head;}static int tieBreakOrder(Object a, Object b) {int d;if (a == null || b == null ||(d = a.getClass().getName().compareTo(b.getClass().getName())) == 0)d = (System.identityHashCode(a) <= System.identityHashCode(b) ?-1 : 1);return d;}final TreeNode<K, V> putTreeVal(MyHashMap<K, V> map, Node<K, V>[] tab,int h, K k, V v) {Class<?> kc = null;boolean searched = false;TreeNode<K, V> root = root();TreeNode<K, V> p = root;while (true) {int dir;int ph = p.hash;K pk = p.key;if (h < ph) {dir = -1;} else if (h > ph) {dir = 1;} else if (pk == k || (k != null && k.equals(pk))) {return p;} else if ((kc == null &&(kc = comparableClassFor(k)) == null) ||(dir = compareComparables(kc, k, pk)) == 0) {if (!searched) {TreeNode<K, V> q, ch;searched = true;ch = p.left;if (ch != null && (q = ch.find(h, k, kc)) != null) {return q;}ch = p.right;if (ch != null && (q = ch.find(h, k, kc)) != null) {return q;}}dir = tieBreakOrder(k, pk);}TreeNode<K, V> xp = p;if (dir <= 0)p = p.left;elsep = p.right;if (p == null) {Node<K, V> xpn = xp.next;TreeNode<K, V> x = map.newTreeNode(h, k, v, xpn);if (dir <= 0)xp.left = x;elsexp.right = x;xp.next = x;x.parent = xp;x.prev = xp;if (xpn != null) {((TreeNode<K, V>) xpn).prev = x;}root = balanceInsertion(root, x);moveRootToFront(tab, root);return null;}}}final TreeNode<K, V> find(int h, Object k, Class<?> kc) {TreeNode<K, V> p = this;do {int ph, dir;K pk;TreeNode<K, V> pl = p.left, pr = p.right, q;if ((ph = p.hash) > h)p = pl;else if (ph < h)p = pr;else if ((pk = p.key) == k || (k != null && k.equals(pk)))return p;else if (pl == null)p = pr;else if (pr == null)p = pl;else if ((kc != null ||(kc = comparableClassFor(k)) != null) &&(dir = compareComparables(kc, k, pk)) != 0)p = (dir < 0) ? pl : pr;else if ((q = pr.find(h, k, kc)) != null)return q;elsep = pl;} while (p != null);return null;}final TreeNode<K, V> getTreeNode(int h, Object k) {TreeNode<K, V> p = root();return p.find(h, k, null);}static <K, V> void moveRootToFront(Node<K, V>[] tab, TreeNode<K, V> root) {if (root == null || tab == null || tab.length == 0)return;int len = tab.length;int index = root.hash & (len - 1);TreeNode<K, V> first = (TreeNode<K, V>) tab[index];if (root != first) {tab[index] = root;TreeNode<K, V> rp = root.prev;TreeNode<K, V> rn = (TreeNode<K, V>) root.next;if (rn != null)rn.prev = rp;if (rp != null)rp.next = rn;if (first != null)first.prev = root;root.next = first;root.prev = null;}}final void split(MyHashMap<K, V> map, Node<K, V>[] tab, int index, int bit) {TreeNode<K, V> b = this;TreeNode<K, V> loHead = null, loTail = null;TreeNode<K, V> hiHead = null, hiTail = null;int lc = 0, hc = 0;for (TreeNode<K, V> e = b, next; e != null; e = next) {next = (TreeNode<K, V>) e.next;e.next = null;if ((e.hash & bit) == 0) {if ((e.prev = loTail) == null) {loHead = e;} else {loTail.next = e;}loTail = e;++lc;} else {if ((e.prev = hiTail) == null) {hiHead = e;} else {hiTail.next = e;}hiTail = e;++hc;}}if (loHead != null) {if (lc <= UNTREEIFY_THRESHOLD) {tab[index] = loHead.untreeify(map);} else {tab[index] = loHead;if (hiHead != null) {loHead.treeify(tab);}}}if (hiHead != null) {if (hc <= UNTREEIFY_THRESHOLD) {tab[index + bit] = hiHead.untreeify(map);} else {tab[index + bit] = hiHead;if (loHead != null) {hiHead.treeify(tab);}}}}static <K, V> TreeNode<K, V> rotateLeft(TreeNode<K, V> root, TreeNode<K, V> p) {if (p == null || p.right == null)return root;TreeNode<K, V> pp = p.parent; TreeNode<K, V> pr = p.right; TreeNode<K, V> prl = pr.left;p.right = prl;if (prl != null) {prl.parent = p;}pr.parent = pp;if (pp == null) {root = pr;root.red = false;} else if (p == pp.left) {pp.left = pr;} else {pp.right = pr;}pr.left = p;p.parent = pr;return root;}static <K, V> TreeNode<K, V> rotateRight(TreeNode<K, V> root, TreeNode<K, V> p) {if (p == null || p.left == null)return root;TreeNode<K, V> pp = p.parent;TreeNode<K, V> pl = p.left;TreeNode<K, V> plr = pl.left;p.left = plr;if (plr != null) {plr.parent = p;}pl.parent = pp;if (pp == null) {root = pl;root.red = false;} else if (p == pp.left) {pp.left = pl;} else {pp.right = pl;}pl.right = p;p.parent = pl;return root;}static <K, V> TreeNode<K, V> balanceInsertion(TreeNode<K, V> root,TreeNode<K, V> x) {x.red = true;TreeNode<K, V> xp, xpp, xppl, xppr;while (true) {xp = x.parent;if (xp == null) {x.red = false;return x;} else if (!xp.red) {return root;} else {xpp = xp.parent;if (xpp == null) {return root;}}xppl = xpp.left;xppr = xpp.right;if (xp == xppl) {if (xppr != null && xppr.red) {xppr.red = false;xp.red = false;xpp.red = true;x = xpp;} else {if (x == xp.right) {x = xp;root = rotateLeft(root, x);xp = x.parent;xpp = xp == null ? null : xp.parent;}if (xp != null) {xp.red = false;if (xpp != null) {xpp.red = true;root = rotateRight(root, xpp);}}}} else {if (xppl != null && xppl.red) {xppl.red = false;xp.red = false;xpp.red = true;x = xpp;} else {if (x == xp.left) {x = xp;root = rotateRight(root, x);xp = x.parent;xpp = xp == null ? null : xp.parent;}if (xp != null) {xp.red = false;if (xpp != null) {xpp.red = true;root = rotateLeft(root, xpp);}}}}}}final void removeTreeNode(MyHashMap<K, V> map, Node<K, V>[] tab,boolean movable) {int n;if (tab == null || (n = tab.length) == 0)return;int index = (n - 1) & hash;TreeNode<K, V> first = (TreeNode<K, V>) tab[index];if (first == null) {return;}TreeNode<K, V> root = first;TreeNode<K, V> rl;TreeNode<K, V> succ = (TreeNode<K, V>) next;TreeNode<K, V> pred = prev;if (pred == null) {first = succ;tab[index] = succ;} else {pred.next = succ;}if (succ != null) {succ.prev = pred;}if (root.parent != null) {root = root.parent;}if (root == null || root.right == null ||(rl = root.left) == null || rl.left == null) {tab[index] = first.untreeify(map); return;}TreeNode<K, V> p = this;TreeNode<K, V> pl = left;TreeNode<K, V> pr = right;TreeNode<K, V> replacement;if (pl != null && pr != null) {TreeNode<K, V> s = pr;TreeNode<K, V> sl = s.left;while (sl != null) {s = sl;sl = s.left;}boolean c = s.red;s.red = p.red;p.red = c;TreeNode<K, V> sr = s.right;TreeNode<K, V> pp = p.parent;if (s == pr) {p.parent = s;p.left = null;p.right = sr;if (sr != null) {sr.parent = p;}s.right = p;s.left = pl;pl.parent = s;s.parent = pp;if (pp == null) {root = s;} else if (p == pp.left) {pp.left = s;} else {pp.right = s;}} else {TreeNode<K, V> sp = s.parent;p.parent = sp;if (s == sp.left) {sp.left = p;} else {sp.right = p;}p.left = null;p.right = sr;if (sr != null) {sr.parent = p;}s.parent = pp;if (pp == null) {root = s;} else if (p == pp.left) {pp.left = s;} else {pp.right = s;}s.left = pl;s.right = pr;pr.parent = s;}if (sr != null) {replacement = sr;} else {replacement = p;}} else if (pl != null) {replacement = pl;} else if (pr != null) {replacement = pr;}else {replacement = p;}if (replacement != p) {TreeNode<K, V> pp = replacement.parent = p.parent;if (pp == null) {root = replacement;} else if (p == pp.left) {pp.left = replacement;} else {pp.right = replacement;}p.left = p.right = p.parent = null;}TreeNode<K, V> r = p.red ? root : balanceDeletion(root, replacement);if (replacement == p) {TreeNode<K, V> pp = p.parent;p.parent = null;if (pp != null) {if (p == pp.left) {pp.left = null;} else {pp.right = null;}}}}static <K, V> TreeNode<K, V> balanceDeletion(TreeNode<K, V> root,TreeNode<K, V> x) {TreeNode<K, V> xp, xpl, xpr;while (true) {if (x == null || x == root) {return root;} else if ((xp = x.parent) == null) {x.red = false;return x;} else if (x.red) {x.red = false;return root;} else if ((xpl = xp.left) == x) {if ((xpr = xp.right) != null && xpr.red) {xpr.red = false;xp.red = true;root = rotateLeft(root, xp);xpr = (xp = x.parent) == null ? null : xp.right;}if (xpr == null) {System.out.println("..........");x = xp;} else {TreeNode<K, V> sl = xpr.left, sr = xpr.right;if ((sr == null || !sr.red) &&(sl == null || !sl.red)) {xpr.red = true;x = xp;} else {if (sr == null) {sl.red = false;xpr.red = true;root = rotateRight(root, xpr);xpr = (xp = x.parent) == null ? null : xp.right;}if (xpr != null) {xpr.red = xp.red;if ((sr = xpr.right) != null) {sr.red = false;}}if (xp != null) {xp.red = false;root = rotateLeft(root, xp);}x = root;}}} else {if (xpl != null && xpl.red) {xpl.red = false;xp.red = true;root = rotateRight(root, xp);xpl = (xp = x.parent) == null ? null : xp.left;}if (xpl == null) {x = xp;} else {TreeNode<K, V> sl = xpl.left, sr = xpl.right;if ((sl == null || !sl.red) && (sr == null || !sr.red)) {xpl.red = true;x = xp;} else {if (sl == null) {sr.red = false;xpl.red = true;root = rotateLeft(root, xpl);xpl = (xp = x.parent) == null ?null : xp.left;}if (xpl != null) {xpl.red = xp.red;if ((sl = xpl.left) != null)sl.red = false;}if (xp != null) {xp.red = false;root = rotateRight(root, xp);}x = root;}}}}}}TreeNode<K, V> newTreeNode(int hash, K key, V value, Node<K, V> next) {return new TreeNode<>(hash, key, value, next);}Node<K, V> replacementNode(Node<K, V> p, Node<K, V> next) {return new Node<>(p.hash, p.key, p.value, next);}Node<K, V> newNode(int hash, K key, V value, Node<K, V> next) {return new Node<>(hash, key, value, next);}
}