TreeMap

来源:互联网 发布:数据恢复 深圳 编辑:程序博客网 时间:2024/06/10 20:25

1、简介

1.1 TreeMap 简介

TreeMap 是一个有序的key-value集合,它是通过红黑树实现的。
TreeMap 继承于AbstractMap,所以它是一个Map,即一个key-value集合。
TreeMap 实现了NavigableMap接口,意味着它支持一系列的导航方法。比如返回有序的key集合。
TreeMap基于红黑树(Red-Black tree)实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
另外,TreeMap是非同步的。 它的iterator 方法返回的迭代器是fail-fastl的。

1.2TreeMap的构造函数

// 默认构造函数。使用该构造函数,TreeMap中的元素按照自然排序进行排列。TreeMap()// 创建的TreeMap包含MapTreeMap(Map$<$? extends K, ? extends V> copyFrom)// 指定Tree的比较器TreeMap(Comparator$<$? super K> comparator)// 创建的TreeSet包含copyFromTreeMap(SortedMap$<$K, ? extends V> copyFrom)

1.3 继承关系

java.lang.Object   ↳     java.util.AbstractMap<K, V>         ↳     java.util.TreeMap<K, V>public class TreeMap<K,V>    extends AbstractMap<K,V>    implements NavigableMap<K,V>, Cloneable, java.io.Serializable {}

1.4 类图

这里写图片描述

2、源代码

public class TreeMap<K,V>    extends AbstractMap<K,V>    implements NavigableMap<K,V>, Cloneable, java.io.Serializable{    //比较方法的对象    private final Comparator<? super K> comparator;    //根节点    private transient Entry<K,V> root;    //元素个数    private transient int size = 0;    //默认构造    public TreeMap() {        comparator = null;    }    //带比较对象的构造    public TreeMap(Comparator<? super K> comparator) {        this.comparator = comparator;    }    //带子map的构造    public TreeMap(Map<? extends K, ? extends V> m) {        comparator = null;        putAll(m);    }    //带SortedMap的构造函数,SortedMap会成为TreeMap的子集    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) {        }    }    //是否包含key    public boolean containsKey(Object key) {        return getEntry(key) != null;    }    //是否包含value    public boolean containsValue(Object value) {        for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e))            if (valEquals(value, e.value))                return true;        return false;    }    //根据key获得value    public V get(Object key) {        Entry<K,V> p = getEntry(key);        return (p==null ? null : p.value);    }    //获取第一个key    public K firstKey() {        return key(getFirstEntry());    }    //    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")            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;    }    //获取TreeMap中大于或等于key的最小的节点;    final Entry<K,V> getCeilingEntry(K key) {        Entry<K,V> p = root;        while (p != null) {            int cmp = compare(key, p.key);            //key < p.key            if (cmp < 0) {                //向左子树寻找                if (p.left != null)                    p = p.left;                else                    //如果left为null 表示为当前路径的最小值                    return p;            //key > p.key            } else if (cmp > 0) {                //向右子树寻找                if (p.right != null) {                    p = p.right;                } else {                    Entry<K,V> parent = p.parent;                    Entry<K,V> ch = p;                    //如果比所有元素都大,会回溯到根节点,返回null                    //如果一个值小于一个节点,但是又大于此节点左子树的所有值(p.right=null),则进行回溯,回溯到左节点(ch==parent.right条件),返回左节点的父节点。                    //看图比较好理解                    while (parent != null && ch == parent.right) {                        ch = parent;                        parent = parent.parent;                    }                    return parent;                }            } else                //如果相同,直接返回                return p;        }        return null;    }    //与getCeilingEntry类似,就是没有key==p.key的条件    final Entry<K,V> getHigherEntry(K key) {        Entry<K,V> p = root;        while (p != null) {            int cmp = compare(key, p.key);            if (cmp < 0) {                if (p.left != null)                    p = p.left;                else                    return p;            } else {                if (p.right != null) {                    p = p.right;                } else {                    Entry<K,V> parent = p.parent;                    Entry<K,V> ch = p;                    while (parent != null && ch == parent.right) {                        ch = parent;                        parent = parent.parent;                    }                    return parent;                }            }        }        return null;    }    //插入键值    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/else将找到需要插入的位置。如果存在key 替换value        //如果有自定义的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 {            //key不允许为null            if (key == null)                throw new NullPointerException();            @SuppressWarnings("unchecked")                Comparable<? super K> k = (Comparable<? super K>) key;            //使用默认Comparable            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 V remove(Object key) {        //找到节点        Entry<K,V> p = getEntry(key);        if (p == null)            return null;        V oldValue = p.value;        //删除        deleteEntry(p);        return oldValue;    }    //返回key最小的节点 exportEntry使返回的节点不能更改    public Map.Entry<K,V> firstEntry() {        return exportEntry(getFirstEntry());    }    //弹出key最小的节点    public final Map.Entry<K,V> pollFirstEntry() {            //找元素            TreeMap.Entry<K,V> e = subLowest();            //装饰为不可变            Map.Entry<K,V> result = exportEntry(e);            if (e != null)                //删除原节点                m.deleteEntry(e);            return result;        }    //返回Key集    public Set<K> keySet() {        return navigableKeySet();    }    //返回Key集    public NavigableSet<K> navigableKeySet() {        KeySet<K> nks = navigableKeySet;        return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this));    }    //返回节点集    public Set<Map.Entry<K,V>> entrySet() {        EntrySet es = entrySet;        return (es != null) ? es : (entrySet = new EntrySet());    }    //包装为不可变的Entry    static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) {        return (e == null) ? null :            new AbstractMap.SimpleImmutableEntry<>(e);    }    //元素节点类    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;        }    }    //寻找并返回key最小的节点    final Entry<K,V> getFirstEntry() {        Entry<K,V> p = root;        if (p != null)            while (p.left != null)                p = p.left;        return p;    }    //寻找继承者节点(比t大的最小节点)    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;        }    }    //左旋转        /** From CLR */    private void rotateLeft(Entry<K,V> p) {        if (p != null) {            Entry<K,V> r = p.right;            p.right = r.left;            if (r.left != null)                r.left.parent = p;            r.parent = p.parent;            if (p.parent == null)                root = r;            else if (p.parent.left == p)                p.parent.left = r;            else                p.parent.right = r;            r.left = p;            p.parent = r;        }    }    //插入后修正    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;    }}

2.2 遍历

    public static void main(String[] args) {        TreeMap map =new TreeMap();        Object key, value;        //迭代器        Iterator iter = map.entrySet().iterator();        while(iter.hasNext()) {            Map.Entry entry = (Map.Entry)iter.next();            key = (String)entry.getKey();            value = (Integer)entry.getValue();        }        //foreach  推荐        for (Map.Entry<> entry: map.entrySet()) {            key = entry.getKey();            value = entry.getValue();        }        //key集        for (Object key1 : map.keySet()) {            value = map.get(key1);        }        //value集        for (Object value1 : map.values()) {        }    }

2.3 总结

TreeMap是红黑树结构,红黑树是有序的,所以TreeMap也是有序的
TreeMap的键不能为null
TreeMap效率不如HashMap,Map需要有序的场合才使用TreeMap
使用descending*方法可以进行逆序操作

参考;http://www.cnblogs.com/skywang12345/p/3310928.html

原创粉丝点击