1 /*获取红黑树的指定节点*/ 2 final TreeNode<K,V> getTreeNode(int h, Object k) { 3 return ((parent != null) ? root() : this).find(h, k, null);// 从根节点开始查询 4 } 5 6 /*获取红黑树指定节点*/ 7 final TreeNode<K,V> find(int h, Object k, Class<?> kc) { 8 TreeNode<K,V> p = this;// 见213行,此节点p就是根节点,进入循环后p代表当前节点 9 do { 10 int ph, dir; K pk;// 定义当前节点p的hash值ph、相对位置dir、key 11 TreeNode<K,V> pl = p.left, pr = p.right, q// 获取当前节点的左子节点、右子节点 12 if ((ph = p.hash) > h)// 表明目标节点在当前节点的左子节点 13 p = pl; 14 else if (ph < h)// 表明目标节点在当前节点的右子节点 15 p = pr; 16 else if ((pk = p.key) == k || (k != null && k.equals(pk)))// 当前节点的hash值与目标节点hash值相等,且当前节点的key与目标key相等(equals) 17 return p; 18 else if (pl == null)// 当前节点的hash值与目标节点hash值相等,且当前节点的key与目标key不相等(equals) 19 p = pr; 20 else if (pr == null) 21 p = pl; 22 else if ((kc != null || 23 (kc = comparableClassFor(k)) != null) && 24 (dir = compareComparables(kc, k, pk)) != 0)// 当前节点的hash值与目标节点hash值相等,且当前节点的key与目标key不相等(equals),且左子节点与右子节点均不为null,目标key实现Comparable接口,且与当前节点比较不为0 25 p = (dir < 0) ? pl : pr; 26 else if ((q = pr.find(h, k, kc)) != null)// 当前节点的hash值与目标节点hash值相等,且当前节点的key与目标key不相等(equals),且左子节点与右子节点均不为null,目标key没有实现Comparable接口,则直接在右子树中查询,这个方法并没有在左子树中循环,因为这是一个递归方法,先遍历右子树并判断是否查找到,若无则将左子树根节点作为当前节点,不用遍历左子树依然可以覆盖全部情况 27 return q; 28 else 29 p = pl; 30 } while (p != null); 31 return null;// 未找到,返回null 32 }