TreeMap put 操作分析
1 public V put(K key, V value) { 2 //t 表示当前节点,记住这个很重要!先把TreeMap 的根节点root 的引用赋值给当前节点 3 TreeMap.Entry<K,V> t = root; 4 //如果当前节点为null ,即是空树,新增的KV 形成的节点就是根节点 5 if (t == null) { 6 //看似多此一举,实际上预检了Key 是否 可以比较 7 compare(key, key); // type (and possibly null) check 8 // 使用Kv 构造出新的Entry 对象,其中第三个参数就是parent ,根节点没有父亲节点 9 root = new TreeMap.Entry<>(key, value, null); 10 size = 1; 11 modCount++; 12 return null; 13 } 14 // cmp 用来接收比较结果 15 int cmp; 16 TreeMap.Entry<K,V> parent; 17 // split comparator and comparable paths 18 //构造方法中置入的外部比较器 19 Comparator<? super K> cpr = comparator; 20 // 重点步骤:根据二叉树的特性,找到新的节点插入的合适位置 21 if (cpr != null) { 22 //循环的目标:根据key 与当前节点key 不断地进行对比 23 do { 24 //当前节点赋值个父亲节点,故从根节点开始遍历比较 25 parent = t; 26 //比较输入的参数的key和当前节点Key 的大小 27 cmp = cpr.compare(key, t.key); 28 //参数的key 更小,向左边走,把当前节点引用移动至它的左子节点上 29 if (cmp < 0) 30 t = t.left; 31 //参数的key 更大,向右边走,把当前节点引用移动至它的右子节点上 32 else if (cmp > 0) 33 t = t.right; 34 //如果相等,则会残忍的覆盖当前节点的Value 值,并返回更新的前的值 35 else 36 return t.setValue(value); 37 } while (t != null); 38 } 39 //在没有比较器的情况下,调用自然排序的Comparable 比较 40 else { 41 if (key == null) 42 throw new NullPointerException(); 43 @SuppressWarnings("unchecked") 44 Comparable<? super K> k = (Comparable<? super K>) key; 45 do { 46 parent = t; 47 cmp = k.compareTo(t.key); 48 if (cmp < 0) 49 t = t.left; 50 else if (cmp > 0) 51 t = t.right; 52 else 53 return t.setValue(value); 54 } while (t != null); 55 } 56 // 创建Entry 对象,并把parent 置入参数 57 TreeMap.Entry<K,V> e = new TreeMap.Entry<>(key, value, parent); 58 //新节点找到自己的位置,原本以为可以安顿下来---------- 59 if (cmp < 0) 60 //如果比较结果小于0 ,则成为parent 的左孩子 61 parent.left = e; 62 else 63 //如果比较结果大于0 ,则成为parent 的右孩子 64 parent.right = e; 65 //还需要重新对这个节点进行着色,旋转操作,已达到平衡 66 fixAfterInsertion(e); 67 size++; 68 modCount++; 69 //成功插入新节点后,返回null 70 return null; 71 }