1 概述
TreeMap 实现了SortedMap接口,也就是说会按照 key
的大小顺序对 Map 中的元素进行排序,key
大小的评判可以通过其本身的自然顺序(natural ordering),也可以通过构造时传入的比较器(Comparator)。
TreeMap底层通过红黑树(Red-Black tree)实现 ,也就意味着 containsKey()
, get()
, put()
, remove()
都有着 log(n)
的时间复杂度。
先把 TreeMap 源码放上:https://github.com/qianwei4712/JDK1.8.0.25-read/blob/master/src/main/java/java/util/TreeMap.java
关于红黑树,在以前写过的 HashMap 中有简单介绍,可以参考:https://blog.csdn.net/m0_46144826/article/details/106300438
源码注解不会覆盖100%,只会阅读重点特性和方法。实在是上一篇 HashMap 把人弄残废了。
2 TreeMap 继承关系
-
实现 Serializable 接口开启序列化功能 ----具体介绍请转 Java面向对象基础 - 异常、序列化
-
实现 Cloneable 接口,允许使用 clone() 方法克隆 — 具体介绍请转 Java面向对象基础 - Object通用方法
-
AbstractMap 抽象类提供了 Map 的基础实现,使得 TreeMap 不需要从零开始实现一个 map 的所有方法。
-
然后剩下的 NavigableMap 和 SortedMap 实现了元素的比较,确定优先级,后面再详细讲。
3 SortedMap、NavigableMap
先把代码注释放上:
-
SortedMap 接口源码 :https://github.com/qianwei4712/JDK1.8.0.25-read/blob/master/src/main/java/java/util/SortedMap.java
-
NavigableMap 接口源码 :https://github.com/qianwei4712/JDK1.8.0.25-read/blob/master/src/main/java/java/util/NavigableMap.java
SortedMap 是 NavigableMap 的父类。
SortedMap 是一个根据 key进排序的 Map 集合,接口设计要求实现一个 comparator 比较器,如果没有实现,则使用元素自带的比较器。
所以 SoryedMap 的 key 必须实现 Comparable 接口
NavigableMap 在 SortedMap 基础上进行了一些功能增强,具体功能见下表:
SortedMap 接口方法:
方法、参数、返回值 | 功能介绍 |
---|---|
Comparator<? super K> comparator(); | 返回用于在此 map中对键进行排序的比较器;如果此映射使用其键的 Comparable 自然排序,则返回 null。 |
SortedMap<K,V> subMap(K fromKey, K toKey); | 返回此地图部分的视图,其键范围为 fromKey(包括边界) 到 toKey(不包括) |
SortedMap<K,V> headMap(K toKey); | 返回此地图部分的视图,其键范围为起始节点到 toKey(不包括) |
SortedMap<K,V> tailMap(K fromKey); | 此地图部分的视图,其键范围为 fromKey(包括边界) 到结束 |
K firstKey(); | 当前在此地图中的第一个(最小)键 |
K lastKey(); | 当前在此地图中的最后一个(最大)键 |
Set keySet(); | 此 map中包含的 key的set集合,以 key比较后升序排列 |
Collection values(); | 此 map中包含的 value值的集合,按 key比较后升序排列 |
Set<Map.Entry<K, V>> entrySet(); | 此 map中包含的键值对的集合视图,按key比较后升序排列 |
NavigableMap 接口添加的方法:
方法、参数、返回值 | 功能介绍 |
---|---|
Map.Entry<K,V> lowerEntry(K key); | 返回严格小于给定键的最大键值对,或者如果没有这样的键。 |
K lowerKey(K key); | 返回严格小于给定键的最大键,或者如果没有这样的键。 |
Map.Entry<K,V> floorEntry(K key); | 返回小于或等于给定键的最大键值对,或者如果没有这样的键。 |
K floorKey(K key); | 返回小于或等于给定键的最大键,或者如果没有这样的键。 |
Map.Entry<K,V> ceilingEntry(K key); | 返回大于或等于给定键的最小键值对,或者如果没有这样的键。 |
K ceilingKey(K key); | 返回大于或等于给定键的最小键,或者如果没有这样的键。 |
Map.Entry<K,V> higherEntry(K key); | 返回严格大于给定键的最小键值对,或者如果没有这样的键。 |
K higherKey(K key); | 返回严格大于给定键的最小键,或者如果没有这样的键。 |
Map.Entry<K,V> firstEntry(); | 返回第一个(最小)键值对,如果不存在返回null |
Map.Entry<K,V> lastEntry(); | 返回最后一个(最大)键值对,如果不存在返回null |
Map.Entry<K,V> pollFirstEntry(); | 返回第一个(最小)键值对并移除,如果不存在返回null |
Map.Entry<K,V> pollLastEntry(); | 返回最后一个(最大)键值对并移除,如果不存在返回null |
NavigableMap<K,V> descendingMap(); | 返回此 map中包含的映射的逆序视图。 |
NavigableSet navigableKeySet(); | 返回一个Navigable的key的集合 |
NavigableSet descendingKeySet(); | 返回一个Navigable的key的倒序集合 |
4 TreeMap 构造方法
TreeMap 真正的参数就以下:
/**
* 比较器用于维护此树形图中的顺序;如果比较器使用其键的自然顺序,则为null。
*/
private final Comparator<? super K> comparator;
/**
* 根节点
*/
private transient Entry<K,V> root;
/**
* treemap节点数
*/
private transient int size = 0;
/**
* 修改次数,快速失败机制
*/
private transient int modCount = 0;
其他还有三个提供遍历的参数,不过这些貌似并不重要 :
private transient EntrySet entrySet;//键值对遍历
private transient KeySet<