Java的TreeMap底层实现原理?( 四 )

put源码逻辑比较简单:

  1. 判断红黑树根节点是否为空,如果为空,则创建根节点 。
  2. 判断是否传入了排序方式,如果没有则使用默认,否则使用自定义排序 。
  3. 循环遍历红黑树,利用红黑树节点左小右大的特性,进行查找 。
  4. 如果找到,就覆盖 。如果没找到,就插入新节点 。
  5. 插入新节点后,调整红黑树节点位置,保持红黑树的特性 。
get源码再看一下get源码:
/** * get源码入口 */public V get(Object key) {    // 调用查找节点的方法    Entry<K, V> p = getEntry(key);    return (p == null ? null : p.value);}/** * 查找节点方法 */final Entry<K, V> getEntry(Object key) {    // 1. 判断如果传入了排序方式,则使用排序方式查找节点    if (comparator != null) {        return getEntryUsingComparator(key);    }    if (key == null) {        throw new NullPointerException();    }    // 2. 否则使用默认方式查找    Comparable<? super K> k = (Comparable<? super K>) key;    Entry<K, V> p = root;    // 3. 利用红黑树节点左小右大的特性 , 循环查找    while (p != null) {        int cmp = k.compareTo(p.key);        if (cmp < 0) {            p = p.left;        } else if (cmp > 0) {            p = p.right;        } else {            return p;        }    }    return null;}/** * 使用传入的排序方式,查找节点方法 */final Entry<K, V> getEntryUsingComparator(Object key) {    K k = (K) key;    Comparator<? super K> cpr = comparator;    if (cpr != null) {        Entry<K, V> p = root;        // 3. 跟上面类似 , 利用红黑树节点左小右大的特性,循环查找        while (p != null) {            int cmp = cpr.compare(k, p.key);            if (cmp < 0) {                p = p.left;            } else if (cmp > 0) {                p = p.right;            } else {                return p;            }        }    }    return null;}get方法源码与put方法逻辑类似,都是利用红黑树的特性遍历红黑树 。
总结TreeMap是一种有序Map集合,具有以下特性:
  1. 保证以键的顺序进行排列
  2. 具有一些以键的顺序进行范围查询的方法,比如firstEntry()、lastEntry()、higherEntry(K key)、 lowerEntry(K key) 等 。
  3. 可以自定义排序方式,初始化的时候,可以指定是正序、倒序或者自定义排序 。
  4. 不允许key为null , 因为null值无法比较大小 。
  5. 底层基于红黑树实现,查找、插入、删除的时间复杂度是O(log n) , 而HashMap的时间复杂度是O(1) 。


    推荐阅读