zoukankan      html  css  js  c++  java
  • 很多地方都用到了的Entry的源码,实现了Map.Entry接口及红黑树的put方法实现

      比如TreeMap的底层实现是基于的红黑树,其中每个节点就是Entry<K,V>:

    static final class Entry<K,V> implements Map.Entry<K,V> {
        //key,val是存储的原始数据
        K key;
        V value;
        //定义了节点的左孩子
        Entry<K,V> left;
        //定义了节点的右孩子
        Entry<K,V> right;
        //通过该节点可以反过来往上找到自己的父亲
        Entry<K,V> parent;
        //默认情况下为黑色节点,可调整
        boolean color = BLACK;
    
        /**
         * 构造器
         */
        Entry(K key, V value, Entry<K,V> parent) {
            this.key = key;
            this.value = value;
            this.parent = parent;
        }
    
        /**
         * 获取节点的key值
         */
        public K getKey() {return key;}
    
        /**
         * 获取节点的value值
         */
        public V getValue() {return value;}
    
        /**
         * 用新值替换当前值,并返回当前值
         */
        public V setValue(V value) {
            V oldValue = this.value;
            this.value = value;
            return oldValue;
        }
    
        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
            return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
        }
    
        public int hashCode() {
            int keyHash = (key==null ? 0 : key.hashCode());
            int valueHash = (value==null ? 0 : value.hashCode());
            return keyHash ^ valueHash;
        }
    
        public String toString() {
            return key + "=" + value;
        }
    }
    

      红黑树的put()方法实现:

    private void fixAfterInsertion(Entry<K,V> x) {
        //新插入的节点为红色节点
        x.color = RED;
        //我们知道父节点为黑色时,并不需要进行树结构调整,只有当父节点为红色时,才需要调整
        while (x != null && x != root && x.parent.color == RED) {
            //如果父节点是左节点,对应上表中情况1和情况2
            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);
                    }
                    //设置父节点和祖父节点颜色
                    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;
    }
    

      

  • 相关阅读:
    简单工厂和抽象工厂有什么区别?
    常用的设计模式有哪些?
    常见的HTTP协议状态码?
    数据库分库分表(sharding)系列(二) 全局主键生成策略
    关于垂直切分Vertical Sharding的粒度
    数据库分库分表(sharding)系列(四) 多数据源的事务处理
    分库分表带来的完整性和一致性问题
    [置顶] 深入探析Java线程锁机制
    为啥RESTFULL如此重要?
    hadoop核心逻辑shuffle代码分析-map端
  • 原文地址:https://www.cnblogs.com/dashenaichicha/p/12726659.html
Copyright © 2011-2022 走看看