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);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)