2019-01-11

一、继承关系

继承AbstractMap 实现了NavigableMap方法(扩展的SortedMap接口)导航方法,

内部类Entry,红黑树节点

Entryleft;

Entryright;

Entryparent;

boolean color =BLACK; 


3、构造器:

无参构造器:

可以不使用比较器,但是key对象必须实现Comparable接口

public TreeMap() {    comparator =null;} 

指定比较器构造器:指定比较器后对key的大小比较使用这个比较器进行比较

public TreeMap(Comparator<? super K> comparator) {     

      this.comparator = comparator;   

map构造器,把map转为treeMap,这里map可以为有序的,也可以是无序

public TreeMap(Map<? extends K, ? extends V> m) {

    comparator = null;       

    putAll(m);   

有序map构造器:

public TreeMap(SortedMap m) {       

comparator = m.comparator();

try {   

     buildFromSorted(m.size(), m.entrySet().iterator(),null,null);

}catch (java.io.IOException cannotHappen) {

}catch (ClassNotFoundException cannotHappen) {

}} 

Map转treeMap的putAll方法:

public void putAll(Map<? extends K, ? extends V> map) {   

    int mapSize = map.size();   

    if (size==0 && mapSize!=0 && map instanceof SortedMap) {

    直接获取sortMap的比较器           

    Comparator<?> c = ((SortedMap<?,?>)map).comparator();

     if (c == comparator || (c != null && c.equals(comparator))) { 

              ++modCount;

                try {

//对map进行转换为红黑树,入参为map的size和迭代器                    buildFromSorted(mapSize, map.entrySet().iterator(),  null, null); 

              } catch (java.io.IOException cannotHappen) {                } catch (ClassNotFoundException cannotHappen) {                }                return;            }        }//如果不是有序的map走put方法构建红黑树        super.putAll(map);    } 


private void buildFromSorted(int size, Iterator<?> it,

                                java.io.ObjectInputStream str,

                                V defaultVal)

        throws  java.io.IOException, ClassNotFoundException {

        this.size = size;

//

        root = buildFromSorted(0, 0, size-1, computeRedLevel(size),

                              it, str, defaultVal);

    }

//转换方法

private final Entry<K,V> buildFromSorted(int level, int lo, int hi,

                                            int redLevel,  //红色节点的层数

                                            Iterator<?> it, //迭代器

                                            java.io.ObjectInputStream str, //null

                                            V defaultVal  //null)

        throws  java.io.IOException, ClassNotFoundException {

        /*

        * Strategy: The root is the middlemost element. To get to it, we

        * have to first recursively construct the entire left subtree,

        * so as to grab all of its elements. We can then proceed with right

        * subtree.

        *

        * The lo and hi arguments are the minimum and maximum

        * indices to pull out of the iterator or stream for current subtree.

        * They are not actually indexed, we just proceed sequentially,

        * ensuring that items are extracted in corresponding order.

        */

        if (hi < lo) return null;

//取中间值作为中间节点

        int mid = (lo + hi) >>> 1;

        Entry<K,V> left  = null;

        if (lo < mid)

//迭代构建左子树。()

            left = buildFromSorted(level+1, lo, mid - 1, redLevel, it, str, defaultVal);

        K key;

        V value;

        if (it != null) {

            if (defaultVal==null) {

                Map.Entry<?,?> entry = (Map.Entry<?,?>)it.next();

                key = (K)entry.getKey();

                value = (V)entry.getValue();

            } else {

                key = (K)it.next();

                value = defaultVal;

            }

        } else { // use stream

            key = (K) str.readObject();

            value = (defaultVal != null ? defaultVal : (V) str.readObject());

        }

        Entry<K,V> middle =  new Entry<>(key, value, null);

        // color nodes in non-full bottommost level red

//涂色

        if (level == redLevel)

            middle.color = RED;

        if (left != null) {

            middle.left = left;

            left.parent = middle;

        }

//构建右子树

        if (mid < hi) {

            Entry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel,

                                              it, str, defaultVal);

            middle.right = right;

            right.parent = middle;

        }

        return middle;

    }

//get方法根据平衡二叉树进行搜索,比根节点小的在左子树,比根节点大的在右子树

final Entry<K,V> getEntry(Object key) {

        // Offload comparator-based version for sake of performance

//如果是有比较器走比较器查找

        if (comparator != null)

            return getEntryUsingComparator(key);

        if (key == null)

            throw new NullPointerException();

        @SuppressWarnings("unchecked")

//没有比较器使用Key对象的Comparable接口

            Comparable<? super K> k = (Comparable<? super K>) key;

        Entry<K,V> p = root;

        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;

    }

public V put(K key, V value) {

        Entry<K,V> t = root;

如果是根节点

        if (t == null) {

//检查一下是否有比较器或者key对象是否实现Comparable接口,如果key没有实现Comparable接口会直接报类型转换异常

            compare(key, key); // type (and possibly null) check

//设置为根节点

            root = new Entry<>(key, value, null);

//mapSize++

            size = 1;

            modCount++;

            return null;

        }

        int cmp;

        Entry<K,V> parent;

        // split comparator and comparable paths

//如果不是根节点。遍历红黑树。还是有比较器走比较器没有就走Comparable接口,比当前节点小放左子树。大放右子树

        Comparator<? super K> cpr = comparator;

        if (cpr != null) {

            do {

                parent = t;

                cmp = cpr.compare(key, t.key);

                if (cmp < 0)

                    t = t.left;

                else if (cmp > 0)

                    t = t.right;

                else

                    return t.setValue(value);

            } while (t != null);

        }

        else {

            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<K,V> e = new Entry<>(key, value, parent);

        if (cmp < 0)

            parent.left = e;

        else

            parent.right = e;

//根据红黑树规则再平衡

        fixAfterInsertion(e);

        size++;

        modCount++;

        return null;

    }

//涂色和再平衡算法

private void fixAfterInsertion(Entry<K,V> x) {

//当前节点涂色为红色

  x.color = RED;

//情况1:如果父节点也是红色

        while (x != null && x != root && x.parent.color == RED) {

如果是左子树

            if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {

                Entry<K,V> y = rightOf(parentOf(parentOf(x)));

如果叔叔节点是红色

                if (colorOf(y) == RED) {

//把父节点涂色为黑色

                    setColor(parentOf(x), BLACK);

//叔叔节点也变为黑色

                    setColor(y, BLACK);

//把祖父节点变为红色

                    setColor(parentOf(parentOf(x)), RED);

//把当前节点移动到祖父节点

                    x = parentOf(parentOf(x));

                } else {

//叔叔节点是黑色

                    if (x == rightOf(parentOf(x))) {

//以父节点为中心,左旋

                        x = parentOf(x);

                        rotateLeft(x);

                    }

再把第三个构造器比较器是空,putAll方法:	public void putAll(Map map) {        int mapSize = map.size();		//必须是实现SortedMap的map对象        if (size==0 && mapSize!=0 && map instanceof SortedMap) {			直接获取sortMap的比较器            Comparator c = ((SortedMap)map).comparator();            if (c == comparator || (c != null && c.equals(comparator))) {                ++modCount;                try {					//对map进行转换为红黑树,入参为map的size和迭代器                    buildFromSorted(mapSize, map.entrySet().iterator(),                                    null, null);                } catch (java.io.IOException cannotHappen) {                } catch (ClassNotFoundException cannotHappen) {                }                return;            }        }

                    setColor(parentOf(x), BLACK);

                    setColor(parentOf(parentOf(x)), RED);

                    rotateRight(parentOf(parentOf(x)));

                }

            } else {

                Entry<K,V> y = leftOf(parentOf(parentOf(x)));

                if (colorOf(y) == RED) {

                    setColor(parentOf(x), BLACK);

                    setColor(y, BLACK);

                    setColor(parentOf(parentOf(x)), RED);

                    x = parentOf(parentOf(x));

                } else {

                    if (x == leftOf(parentOf(x))) {

                        x = parentOf(x);

                        rotateRight(x);

                    }

                    setColor(parentOf(x), BLACK);

                    setColor(parentOf(parentOf(x)), RED);

                    rotateLeft(parentOf(parentOf(x)));

                }

            }

        }

        root.color = BLACK;

    }

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容