jdk8源码8---集合7----TreeMap

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wxy540843763/article/details/80640652

一、签名

public class TreeMap<K,V>

    extends AbstractMap<K,V>

    implements NavigableMap<K,V>, Cloneable, java.io.Serializable

NavigableMap:可导航的Map。 Since 1.6. 它实现继承了SortedMap,成为了一个具有搜索匹配算法的Map。和TreeSet类似。

 

二、成员变量

private final Comparator<? super K> comparator; // 比较器。

private transient Entry<K,V> root; // 树的根节点

private transient int size = 0;  // 树的entity数量

private transient int modCount = 0;

static final class Entry<K,V> implements Map.Entry<K,V> {

        K key;    

        V value;

        Entry<K,V> left;

        Entry<K,V> right;

        Entry<K,V> parent;

        boolean color = BLACK;

 

        /**

         * Make a new cell with given key, value, and parent, and with

         * {@code null} child links, and BLACK color.

         */

        Entry(K key, V value, Entry<K,V> parent) {

            this.key = key;

            this.value = value;

            this.parent = parent;

        }

 

        /**

         * Returns the key.

         *

         * @return the key

         */

        public K getKey() {

            return key;

        }

 

        /**

         * Returns the value associated with the key.

         *

         * @return the value associated with the key

         */

        public V getValue() {

            return value;

        }

 

        /**

         * Replaces the value currently associated with the key with the given

         * value.

         *

         * @return the value associated with the key before this method was

         *         called

         */

        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;

        }

    }

 

三、构造方法

public TreeMap() {   //构造一个新的,空的tree map,使用key的自然顺序(没有指定比较器)。

        comparator = null;

    }

public TreeMap(Comparator<? super K> comparator) { // 根据指定的比较器构造一个

        this.comparator = comparator; //新TreeMap

    }

public TreeMap(Map<? extends K, ? extends V> m) {  //将给定的map构造一个新treeMap

        comparator = null;  // 但是按照key的自然顺序排序。

        putAll(m);

    }

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) {

        }

    }//将给定SortMap中的数据根据SortMap中的比较器构造一个新的TreeMap。

 

四、成员方法

public V put(K key, V value) {

        Entry<K,V> t = root;

        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) {

            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")  // 如果没有指定比较器。就将key强转成比较器。

                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;

    }

 

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

        int mapSize = map.size();

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

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

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

                ++modCount;

                try {

                    buildFromSorted(mapSize, map.entrySet().iterator(),

                                    null, null);

                } catch (java.io.IOException cannotHappen) {

                } catch (ClassNotFoundException cannotHappen) {

                }

                return;

            }

        }

        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);

    }

// 从排序序列中构造TreeMap函数。

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

                                             int redLevel,

                                             Iterator<?> it,

                                             java.io.ObjectInputStream str,

                                             V defaultVal)

        throws  java.io.IOException, ClassNotFoundException { //

      

// 树的根节点 肯定是排序序列的中间树。

// 递归处理根节点的左树,右树。

        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);

 

        // extract key and/or value from iterator or stream

        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;

    }

 

查找:

final Entry<K,V> getFirstEntry() {

        Entry<K,V> p = root;

        if (p != null)

            while (p.left != null)

                p = p.left;

        return p;

    }  //中序遍历 获取第一个Entity

final Entry<K,V> getLastEntry() {

        Entry<K,V> p = root;

        if (p != null)

            while (p.right != null)

                p = p.right;

        return p;

    } // 中序遍历  获取最后一个entity。

 

删除

private void deleteEntry(Entry<K,V> p) {

        modCount++;

        size--;

 

        // If strictly internal, copy successor's element to p and then make p

        // point to successor.

        if (p.left != null && p.right != null) {

            Entry<K,V> s = successor(p);

            p.key = s.key;

            p.value = s.value;

            p = s;

        } // p has 2 children

 

        // Start fixup at replacement node, if it exists.

        Entry<K,V> replacement = (p.left != null ? p.left : p.right);

 

        if (replacement != null) {

            // Link replacement to parent

            replacement.parent = p.parent;

            if (p.parent == null)

                root = replacement;

            else if (p == p.parent.left)

                p.parent.left  = replacement;

            else

                p.parent.right = replacement;

 

            // Null out links so they are OK to use by fixAfterDeletion.

            p.left = p.right = p.parent = null;

 

            // Fix replacement

            if (p.color == BLACK)

                fixAfterDeletion(replacement);

        } else if (p.parent == null) { // return if we are the only node.

            root = null;

        } else { //  No children. Use self as phantom replacement and unlink.

            if (p.color == BLACK)

                fixAfterDeletion(p);

 

            if (p.parent != null) {

                if (p == p.parent.left)

                    p.parent.left = null;

                else if (p == p.parent.right)

                    p.parent.right = null;

                p.parent = null;

            }

        }

    }

static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {

        if (t == null)

            return null;

        else if (t.right != null) {

            Entry<K,V> p = t.right;

            while (p.left != null)

                p = p.left;

            return p;

        } else {

            Entry<K,V> p = t.parent;

            Entry<K,V> ch = t;

            while (p != null && ch == p.right) {

                ch = p;

                p = p.parent;

            }

            return p;

        }

    }

 

五、遍历方式

六、总结

1.  红黑树。

从Entiry这个内部类可以看出,TreeMap是使用红黑树这种数据结构来实现的。(Bythe way, hashMap中也用到了红黑树。)

大体上说一下红黑树的性质吧,这个我会在以后学习一下的。。。。。。。。

每个节点或是red,或是Black。

根节点是Black的。

每个叶子节点NIL是black的。

如果一个节点是Red,那么它的两个子节点都是Black。

对于每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的Black节点。

2.  TreeMap在涉及到树形结构变化的时候,所实现的代码都是根据算法导论中的伪代码来的。

如果想研究一下红黑树的变化原理,请参考这篇文章:http://www.importnew.com/20413.html


猜你喜欢

转载自blog.csdn.net/wxy540843763/article/details/80640652