美文网首页技术干货Android知识程序员
源码的魅力 - TreeMap 的工作原理

源码的魅力 - TreeMap 的工作原理

作者: Nichool | 来源:发表于2017-09-14 21:58 被阅读0次

    源码的魅力 - TreeMap 的工作原理(Android 7.1源码)

    简介

    由于HashMap与linkedHashMap都不能按照key的数据顺序进行遍历,所以后来就有了TreeMap。

    怎么做到按照插入顺序排序的呢

        public TreeMap(Comparator<? super K> comparator) {
            this.comparator = comparator;
        }
    
        public V put(K key, V value) {
            TreeMapEntry<K,V> t = root;
            if (t == null) {
                if (comparator != null) {
                    if (key == null) {
                        comparator.compare(key, key);
                    }
                } else {
                    if (key == null) {
                        throw new NullPointerException("key == null");
                    } else if (!(key instanceof Comparable)) {
                        throw new ClassCastException(
                                "Cannot cast" + key.getClass().getName() + " to Comparable.");
                    }
                }
    
                root = new TreeMapEntry<>(key, value, null);
                size = 1;
                modCount++;
                return null;
            }
            int cmp;
            TreeMapEntry<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")
                    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);
            }
            TreeMapEntry<K,V> e = new TreeMapEntry<>(key, value, parent);
            if (cmp < 0)
                parent.left = e;
            else
                parent.right = e;
            fixAfterInsertion(e);
            size++;
            modCount++;
            return null;
        }
    

    TreeMap存在一个参数为Comparator的构造函数,在插入数据时默认是使用数据的默认比较器,否则使用比较器,通过比较器比较的值,如果相等则直接替换,如果不同则插入,使用红黑树维护整个结构。

    怎么获取数据时是有序的呢

        abstract class PrivateEntryIterator<T> implements Iterator<T> {
            TreeMapEntry<K,V> next;
            TreeMapEntry<K,V> lastReturned;
            ...
    
            final TreeMapEntry<K,V> nextEntry() {
                TreeMapEntry<K,V> e = next;
                if (e == null)
                    throw new NoSuchElementException();
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                next = successor(e);
                lastReturned = e;
                return e;
            }
        }
    
        //中序遍历查找下一个节点
        static <K,V> TreeMapEntry<K,V> successor(TreeMapEntry<K,V> t) {
            if (t == null)
                return null;
            else if (t.right != null) {
                TreeMapEntry<K,V> p = t.right;
                while (p.left != null)
                    p = p.left;
                return p;
            } else {
                TreeMapEntry<K,V> p = t.parent;
                TreeMapEntry<K,V> ch = t;
                while (p != null && ch == p.right) {
                    ch = p;
                    p = p.parent;
                }
                return p;
            }
        }
    

    通过PrivateEntryIterator遍历器然后,通过中序遍历返回数据,正是排序的数据。

    相关文章

      网友评论

        本文标题:源码的魅力 - TreeMap 的工作原理

        本文链接:https://www.haomeiwen.com/subject/ipjjsxtx.html