JDK容器学习之TreeMap (一) : 底层结构&应用场景

TreeMap底层数据结构

在日常的工作中,相比较与HashMap而言,TreeMap的使用会少很多,即使在某些场景,需要使用到排序的Map时,也更多的是选择LinkedHashMap,那么这个TreeMap到底是个怎样的容器,又适用于什么样的应用场景呢?


1. 数据结构分析


分析数据结构,最好的方式无疑是google+baidu+源码了

1. 继承体系

看到源码第一眼,就会发现与HashMap不同的是 TreeMap 实现的是NavigableMap, 而不是直接实现Map

有必要仔细看下这个NavigableMap,到底有些什么特殊之处

继承体系:

Map -> SortMap -> NavigbleMap

其中SortMap新增了下面几个接口,目前也不知道具体有啥用,先翻译下源码注释

接着就是NavigableMap定义的接口

基本上这两个接口就是提供了一些基于排序的获取kv对的方式

2. 数据结构

看下内部的成员变量,发现可能涉及到数据结构的就只有下面的这个root了

private transient Entry<K,V> root;

结合TreeMap的命名来看,底层的结构多半就真的是Tree了,有树的根节点,一般来讲遍历都是没啥问题的

接下来看下 Entry的实现

从Entry的内部成员变量可以看出,这是一个二叉树,且极有可能就是一颗红黑树(因为有个black)

2. 添加一个kv对


通过新增一个kv对的调用链,来分析下这棵树,到底是不是红黑树

将put方法捞出来, 然后补上注释

从添加逻辑,可以得出结论:

  1. 树结构为二叉排序树(且不能出现相等的情况)

  2. 重排的方法可以保证该树为红黑树

所以新增一个kv对的逻辑就比较简单了

遍历树,将kv对作为叶子节点存在对应的位置

3. 使用说明


TreeMap 的优点

1. 红黑树,先天支持排序TreeMap根绝key进行比较排序

  • 支持自定义实现的比较器

  • key实现Comparable接口HashMap无排序功能

2. 存储空间少

  • Treemap红黑树中一个节点对应一个kv对,没有冗余无效的Node节点

  • HashMap的数组中,可能存在较多的空位

TreeMap 的缺点

1. 查询的时间复杂度

正常来讲,TreeMap 的查询时间复杂度为O(logN), 而HashMap为O(1)

所以Map的元素越多,TreeMap根据key查询的效率会更低;

另一方面,HashMap在糟糕的情况下,可能退化为链表

2. 修改导致重排

TreeMap 每次新增or删除一个kv对,都可能导致红黑树的重排HashMap

当新增一个kv对,使得Map中的个数大于阀值时,需要对数组进行重新扩容

使用场景

通过上面的优缺点对比,可以看出TreeMap和HashMap两者的使用场景差别算是比较大的

对Map中的kv对有排序需求时,选择TreeMap, 这种场景下,尽量保证以下几点

  • Map 元素基本保持不变(即很少添加和删除)

  • 主要用于遍历迭代获取数据

  • 不存在碰撞的情况(即两个不同的key,根据比较器获取值不能为0)

4. 小结


红黑树相关可以作为独立的一个知识点,这里不详细展开,基本上通过上面的分析,可以得出下面几个点

  1. TreeMap 底层结构为红黑树

  2. 红黑树的Node排序是根据Key进行比较

  3. 每次新增删除节点,都可能导致红黑树的重排

  4. 红黑树中不支持两个or已上的Node节点对应红黑值相等

5. 扫码关注,获取更多资讯


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值