JDK之TreeMap源码解读(二)

TreeMap根据其key的可比较自然顺序或通过创建map时提供的Comparator对Map进行排序,具体取决于使用的构造函数。

此实现为containsKey、get、put和remove操作提供了保证的log(n)的时间复杂度。算法是对Cormen、Leiserson和Rivest算法介绍中的算法的改编。

请注意,如果要正确实现map接口,TreeMap维护的顺序就像任何sorted map一样,无论是否提供显式comparator,都必须与equals一致。(请参见Comparable或Comparator以获得与equals一致的精确定义)。这是因为Map接口是根据equals操作定义的,但sorted map是使用其CompareTo(或Compare)方法执行所有key比较,因此,这种方法认为相等的两个key,从sorted map的角度来看,是相等的。

注意,当前的实现是没有经过同步处理的。如果多个线程同时访问该map,而且至少一个线程结构化修改了map,就必须通过外部操作来同步。(结构化修改是指添加或删除一个或多个map的任何操作;仅更改与现有key关联的value不是结构化修改)。这通常是通过在封装了map的某个对象上进行同步来完成的。

如果不存在此类对象,则应使用Collections.synchronizedSortedMap方法来封装map。这最好在创建时完成,以防止意外未同步访问map:

SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...))

此类中方法返回的所有Map.Entry及其视图表示生成map时map的快照,它们不支持Entry.setValue方法。(但请注意,可以使用put更改相关map中的映射)。

成员属性:

    //TreeMap用来排序的比较器,如果为null,说明使用key的自然排序 
    private final Comparator<? super K> comparator;
    
    //TreeMap的根节点,类型是Entry键值对
    private transient Entry<K,V> root;

    //TreeMap中entry的个数
    private transient int size = 0;

    //对树的结构修改的次数
    private transient int modCount = 0;

其中,Entry<K,V>是TreeMap的节点,它是TreeMap的一个静态内部类,实现了Map.Entry<K,V>接口,并且扩展了一些功能。

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;

        //用指定的key、value、父节点、空的子节点、黑色,来创建一个单元
        Entry(K key, V value, Entry<K,V> parent) {
            this.key = key;
            this.value = value;
            this.parent = parent;
        }

        //返回当前节点的key
        public K getKey() {
            return key;
        }

        //返回当前节点的key对应的value
        public V getValue() {
            return value;
        }

        //将当前节点的value设置成指定的value,并返回旧的value
        public V setValue(V value) {
            V oldValue = this.value;
            this.value = value;
            return oldValue;
        }

        //比较当前节点和Object o 是否相等
        public boolean equals(Object o) {
            //如果Object o 不是Map.Entry类型,返回false
            if (!(o instanceof Map.Entry))
                return false;
            //将Object o 强转成Map.Entry
            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
            //比较两个Entry的key和value是否都相等
            return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
        }

        //计算当前节点的hash值
        public int hashCode() {
            int keyHash = (key==null ? 0 : key.hashCode());
            int valueHash = (value==null ? 0 : value.hashCode());
            //将key的hash值和value的hash值进行异或运算
            return keyHash ^ valueHash;
        }

        //重写toString方法
        public String toString() {
            return key + "=" + value;
        }
    }

构造方法:

    //使用key的自然排序,创建一个新的、空的TreeMap
    public TreeMap() {
            comparator = null;
    }

    //根据指定的Comparator,创建一个新的、空的TreeMap
    public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }

    //根据key的自然排序,创建一个新的、包含指定map的所有映射的TreeMap
    public TreeMap(Map<? extends K, ? extends V> m) {
        comparator = null;
        putAll(m);
    }

    //根据参数中SortedMap的comparator,创建一个新的、包含指定map的所有映射的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) {
        }
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值