代码语言:javascript复制
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 }