• TreeMap源码分析


    TreeMap是基于红黑树来实现的,它是根据键的自然顺序,或者创建时提供的comparator来排序的。

    1.属性

         /**
         * The comparator used to maintain order in this tree map, or
         * null if it uses the natural ordering of its keys.
         * TreeMap中的映射排序是根据此comparator来排序的,如果此comparator为null,则根据键的自然顺序排序
         * @serial
         */
        private final Comparator<? super K> comparator;
        // 根元素
        private transient Entry<K,V> root = null;
    
        /**
         * The number of entries in the tree
    * 元素的数量
    */ private transient int size = 0; /** * The number of structural modifications to the tree.
    * TreeMap修改的次数
    */ private transient int modCount = 0;

    2.构造器

      /**
         * Constructs a new, empty tree map, using the natural ordering of its
         * keys.  All keys inserted into the map must implement the {@link
         * Comparable} interface.  Furthermore, all such keys must be
         * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw
         * a {@code ClassCastException} for any keys {@code k1} and
         * {@code k2} in the map.  If the user attempts to put a key into the
         * map that violates this constraint (for example, the user attempts to
         * put a string key into a map whose keys are integers), the
         * {@code put(Object key, Object value)} call will throw a
         * {@code ClassCastException}.
         */
        public TreeMap() {
            comparator = null;
        }
    
        /**
         * Constructs a new, empty tree map, ordered according to the given
         * comparator.  All keys inserted into the map must be <em>mutually
         * comparable</em> by the given comparator: {@code comparator.compare(k1,
         * k2)} must not throw a {@code ClassCastException} for any keys
         * {@code k1} and {@code k2} in the map.  If the user attempts to put
         * a key into the map that violates this constraint, the {@code put(Object
         * key, Object value)} call will throw a
         * {@code ClassCastException}.
         *
         * @param comparator the comparator that will be used to order this map.
         *        If {@code null}, the {@linkplain Comparable natural
         *        ordering} of the keys will be used.
    * 构造一个空的TreeMap,根据指定的comparator来排序
    */ public TreeMap(Comparator<? super K> comparator) { this.comparator = comparator; } /** * Constructs a new tree map containing the same mappings as the given * map, ordered according to the <em>natural ordering</em> of its keys. * All keys inserted into the new map must implement the {@link * Comparable} interface. Furthermore, all such keys must be * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw * a {@code ClassCastException} for any keys {@code k1} and * {@code k2} in the map. This method runs in n*log(n) time. * * @param m the map whose mappings are to be placed in this map * @throws ClassCastException if the keys in m are not {@link Comparable}, * or are not mutually comparable * @throws NullPointerException if the specified map is null
    * 构造一个TreeMap,包含给定的Map,按照key的自然顺序排序,key要实现Comparable接口
    */ public TreeMap(Map<? extends K, ? extends V> m) { comparator = null; putAll(m); } /** * Constructs a new tree map containing the same mappings and * using the same ordering as the specified sorted map. This * method runs in linear time. * * @param m the sorted map whose mappings are to be placed in this map, * and whose comparator is to be used to sort this map * @throws NullPointerException if the specified map is null
    * 构造一个TreeMap,包含指定的Map,按照给定的SortedMap的排序规则进行排序
    */ public TreeMap(SortedMap<K, ? extends V> m) { comparator = m.comparator(); try { buildFromSorted(m.size(), m.entrySet().iterator(), null, null); } catch (java.io.IOException cannotHappen) { } catch (ClassNotFoundException cannotHappen) { } }

     3.方法

    3.1:V put(K key,V value):将指定值与此映射中的指定键进行关联。如果该映射以前包含此键的映射关系,那么将替换旧值

    插入操作可以分为两步:一是将该TreeMap看做一个二叉树来操作,找到将要插入的位置,然后进行插入操作。二是当插入操作完成后,为了保证红黑树的特性,需要对红黑树调整:节点旋转和颜色改变

     public V put(K key, V value) {
            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; }
    // key值比较大小返回的比较结果
    int cmp; Entry<K,V> parent; // split comparator and comparable paths Comparator<? super K> cpr = comparator;
    // Comparator不为空的情况下,使用comparator来比较key值的大小,同时获取新插入节点的父节点parent
    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); }
    // Comparator为null的情况下,使用key的自然顺序进行排序,同时获取新插入节点的父节点parent
    else { if (key == null) throw new NullPointerException(); 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; }

    进入fixAfterInsertion方法:进行节点旋转和颜色改变。可以参照我的另一篇文章:红黑树详解 

     private void fixAfterInsertion(Entry<K,V> x) {
            x.color = RED;
    
            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);
                        }
                        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;
        }

    3.2:V get(Object key):返回指定键所映射的值,如果对于该键而言,此映射不包含任何映射关系,则返回 null

      public V get(Object key) {
            Entry<K,V> p = getEntry(key);
            return (p==null ? null : p.value);
        }
        
    // 对于查找方法,完全是依赖二叉搜索树的特点来进行的,并没有用到红黑树的特性
    final Entry<K,V> getEntry(Object key) { // Offload comparator-based version for sake of performance if (comparator != null)
    // 如果Comparator不为null,则比较器使用Comparator,来获取对应的Value
    return getEntryUsingComparator(key); if (key == null) throw new NullPointerException(); Comparable<? super K> k = (Comparable<? super K>) key; Entry<K,V> p = root;
    // 否则使用key的自然排序来获取Value
    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; }

    3.3 remove (Object key):如果此 TreeMap 中存在该键的映射关系,则将其删除。

  • 相关阅读:
    自相关函数 互相关函数 平稳随机过程
    MC323发短信程序+MSP430F149
    labview notes
    DSSS FHSS
    dBm与功率(w)换算关系!
    int 正负相乘
    51单片机 1602液晶显示
    51单片机 AD转换
    51单片机 蜂鸣器
    51单片机 串口通信
  • 原文地址:https://www.cnblogs.com/51life/p/9364141.html
Copyright © 2020-2023  润新知