TreeMap源码分析

TreeMap源码分析

数据结构

TreeMap使用红黑树来存储数据,红黑树是一种平衡二叉查找树,它是一种高效的搜索算法,它的算法时间复杂度是O(lgn)

增删改查

增改

public V put(K key, V value) {
    // 先获取根节点
    Entry<K,V> t = root;
    // 没有跟节点的话代表TreeMap是空的、直接创建根节点即可
    if (t == null) {
        // 如果key为null则异常、本质是检查key是否为null
        compare(key, key);

        // 创建根节点
        root = new Entry<>(key, value, null);
        // TreeMap长度
        size = 1;
        // 线程安全相关
        modCount++;
        // 返回null、代表是新增、不是修改
        return null;
    }
    // 返回比较结果、 负数: 小于 0: 等于 正数: 大于
    int cmp;
    // 走到这里代表TreeMap不为空的
    Entry<K,V> parent;
    // split comparator and comparable paths
    Comparator<? super K> cpr = comparator;
    
    // if else中是修改节点的值、不存在的话走下面创建节点
    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
                // 比较key相等、直接修改节点的value、返回之前修改的节点value
                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
                // 比较key相等、直接修改节点的value、返回之前修改的节点value
                return t.setValue(value);
        } while (t != null);
    }
    // 创建节点
    Entry<K,V> e = new Entry<>(key, value, parent);
    // 根据上面最后的运算、算出parent的左树节点或者右数节点是空点、直接创建节点返回
   
    if (cmp < 0)
        parent.left = e;
    else
        parent.right = e;
    
    // 由于是新增的节点、需要对树进行修复、确保树是平衡的、即左右两边均衡
    fixAfterInsertion(e);
    // 长度自增
    size++;
    // 线程安全相关
    modCount++;
    // 由于是新增、直接返回null、修改的话返回修改之前的值
    return null;
}

比较

final int compare(Object k1, Object k2) {
    // 可以看到、存在定制排序则调用定制排序、没有则调用自然排序、当key为null时会出现异常、所有不能TreeMap不能传入null、因为没有做null的判断
    return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
        : comparator.compare((K)k1, (K)k2);
}
posted @   鐡道  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示