内部结构

TreeMap 是基于红黑树实现的,增删改查操作的平均和最坏时间复杂度都为 O(log n),其根节点为 key 最小的 entry。

黑红树相比 AVL 树,任何不平衡都能在 3 次旋转之内完成调整,每次向上回溯的步长是 2,对于频繁插入和删除的场景,红黑树的优势非常明显。

TreeMap 的时间复杂度比 HashMap 要高一点,但是合理利用其有序性和稳定性,以及支持范围查找的特性,往往在数据排序场景中特别高效。

key 唯一性机制

TreeMap 的 key 唯一性并不是基于 **equals()** 方法实现的!而是基于 compareTo()compare() 方法实现的,对此你可以查看该类的 put() 方法源码。下面通过一段示例代码进行演示:

  1. public class InstantDemo {
  2. public static void main(String[] args) {
  3. TreeMap<Key, String> map = new TreeMap<>();
  4. map.put(new Key(), "value 1");
  5. map.put(new Key(), "value 2");
  6. map.size(); // return 2, but if map is an object of HashMap. return 1
  7. }
  8. }
  9. class Key implements Comparable<Key> {
  10. @Override
  11. public boolean equals(Object obj) { return true; }
  12. @Override
  13. public int compareTo(Key o) { return -1; }
  14. }

正是因为需要使用 compareTo()compare() 方法保证 key 的唯一性,所以 **TreeMap** 的 key 不允许为 **null** ,但 value 允许为 **null**

TreeSet 与 TreeMap

TreeSet 是基于 TreeMap 实现的, TreeSet 的底层就是一个 TreeMap 对象,所有的 value 共享一个静态 Object 对象,源码如下所示:

  1. // TreeSet
  2. private static final Object PRESENT = new Object();
  3. public boolean add(E e) {
  4. return m.put(e, PRESENT)==null;
  5. }

相比 HashMap,TreeMap 的使用频率相对较少,这里给出一道使用了 TreeSet 结构的题目: