public class TreeMap<K,V>    extends AbstractMap<K,V>    implements NavigableMap<K,V>, Cloneable, java.io.Serializable{    ...}

TreeMap 的接口几继承树中,有两个不同凡响的接口:NavigableMap、SortedMap。SortedMap接口示意它的key是有序不能反复的,反对获取头尾Key-Value 元素,或者更具key指定范畴获取子集合等。插入的key 必须实现Comparable 或者提供额定的Comparator,所以key不容许为null,然而value 能够。NavigablMap接口继承了Sorted Map接口。

如果key没有实现Comparable或者Comparator,那么编译的时候会抛出异样。

import java.util.TreeMap;public class TreeMapDemo {    public static void main(String[] args) {        TreeMap<Person,Integer> tree = new TreeMap<>();        tree.put(new Person(1,"张三"), 1);    }  }class Person{    private int age;    private String name;    getter/setter/constructor/toString    }

output:

Exception in thread "main" java.lang.ClassCastException: class Person cannot be cast to class java.lang.Comparable (Person is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')        at java.base/java.util.TreeMap.compare(TreeMap.java:1291)        at java.base/java.util.TreeMap.put(TreeMap.java:536)        at TreeMapDemo.main(TreeMapDemo.java:6)

重写compareTo办法:

    @Override    public int compareTo(Person o) {        // TODO Auto-generated method stub        return this.getAge() - o.getAge();    }

put办法

public V put(K key, V value) {    // 把root节点给t        Entry<K,V> t = root;    // 如果根节点是null,那么这棵树是空树,新增的节点就是根节点。        if (t == null) {            compare(key, key); // type (and possibly null) check            root = new Entry<>(key, value, null);            size = 1;            modCount++;            return null;        }        int cmp;        Entry<K,V> parent;        // split comparator and comparable paths        // 结构器放入的比拟器        Comparator<? super K> cpr = comparator;        // 比拟器不为空,那么就优先应用比拟器来进行比拟        if (cpr != null) {            // 比拟key值,找到指标地位            do {                // 将以后节点给parent                parent = t;                // 将比拟后果给cmp                cmp = cpr.compare(key, t.key);                // 判断插入的key和以后节点(t)的大小                if (cmp < 0)                    // 如果比以后节点小,当将前节点指向为左子树的根节点                    t = t.left;                else if (cmp > 0)                    t = t.right;                else                    // 如果key相等,就将以后的value复制替换掉原来的value                    return t.setValue(value);            } while (t != null);        }        // 比拟器为null的状况下,应用Comparable接口的compareTo 办法来比拟        else {            // 插入key 为null,抛异样            if (key == null)                throw new NullPointerException();            @SuppressWarnings("unchecked")                Comparable<? super K> k = (Comparable<? super K>) key;            // 和下面的比拟思路一样            do {                parent = t;                cmp = k.compareTo(t.key);                if (cmp < 0)                    t = t.left;                else if (cmp > 0)                    t = t.right;                else                    return t.setValue(value);            } while (t != null);        }        // 创立Entry对象,并把parent对象放入        Entry<K,V> e = new Entry<>(key, value, parent);        // 插入节点        if (cmp < 0)            // 小于parent,插入左子树            parent.left = e;        else            // 插入右子树            parent.right = e;        // 调整红黑树结构,使其合乎规定        fixAfterInsertion(e);        size++;        modCount++;        return null;    }

不须要调整:

须要调整的状况:

 /** From CLR */    private void fixAfterInsertion(Entry<K,V> x) {       // 默认插入新节点的色彩是红色        x.color = RED;        // 须要进行调整的条件        // 父亲节点色彩为红色        while (x != null && x != root && x.parent.color == RED) {          /* 分状况进行调整             x 示意以后节点,p示意parent节点,u示意uncle节点,g示意grandfather节点                        o (g)                       /    \                    o(p)    o(u)                                           o(x)                                      */                          // 如上图                    if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {                // y就是uncle节点                Entry<K,V> y = rightOf(parentOf(parentOf(x)));                // 如果uncle节点是红色                if (colorOf(y) == RED) {                    // 从新染色                    setColor(parentOf(x), BLACK);                    setColor(y, BLACK);                    setColor(parentOf(parentOf(x)), RED);                    x = parentOf(parentOf(x));                } else {                        // uncle节点是彩色                    // 判断以后节点的地位   如图:                    /*                         o (g)                       /    \                    o(p)    o(u)                        \                              o(x)                                       */                     if (x == rightOf(parentOf(x))) {                        x = parentOf(x);                        // 左旋                        rotateLeft(x);                    }                    // 从新染色                    setColor(parentOf(x), BLACK);                    setColor(parentOf(parentOf(x)), RED);                    rotateRight(parentOf(parentOf(x)));                }            } else {             ....// 原理雷同            }        }        root.color = BLACK;    }
private void rotateLeft(Entry<K,V> p) {    // 如果参数节点不是NIL节点        if (p != null) {            // 获取p节点的右子节点            Entry<K,V> r = p.right;            // 将r的左子树设置为p 的右子树            p.right = r.left;            // ,则将p设置为r左子树的父亲            if (r.left != null)                r.left.parent = p;            // 将p 的父亲设置为r 的父亲            r.parent = p.parent;            // 如果p的父亲是null            if (p.parent == null)                root = r;            else if (p.parent.left == p)                p.parent.left = r;            else                p.parent.right = r;            // 将p设置为r的左子树,将r设置为p的父亲            r.left = p;            p.parent = r;        }    }