TreeMap 实现了 SortedMap 和 NavigableMap 接口,所有本文还会记录 SortedMap 和 NavigableMap 的阅读笔记。

SortedMap

1. 排序的比较应该和 equals(Object) 保持一致

2. 应该提供四种“标准”的构造器

  1). 无参构造器

  2). 带一个 Comparator 为参数的构造器

  3). 带一个 Map 为参数的构造器

  4). 带一个 SortedMap 为参数的构造器

3.  subMap ,  headMap ,  tailMap ,  KeySet ,  values,  entrySet  等方法返回的 Map 或 Set 和 SortedMap 本身使用同一份数据,所以对 subMap 返回的 Map 进行修改,同样会反映到 SortedMap 上。

NavigableMap

1. lowerEntry, floorEntry, ceilingEntry, higherEntry 分别返回 小于、小于或等于,大于或等于,以及大于给定 key 的 Map.Entry。这类型的方法用于定位离目标给定值最近的元素。

2. 增长序 map 的操作比递减序的 map 的操作要快。

3. 返回 entry 的方法返回的是那一刻的 entry 快照,所以通常不支持 Entry.setValue 方法。

例如, TreeMap 实现 NavigableMap 的 firstEntry,返回会的就是根据给定 entry 的 key, value 新建的不可变

SimpleImmutableEntry 对象。

4. pollFirstEntry 删除并返回第一个元素

TreeMap

1. 基于红黑树的实现

2. 根据自然序,或者给定的比较器是内部元素保持有序。

3. 提供复杂度为 log(n) 的 containsKey, get, put, remove 操作

4. itertator 采用 fast-fail 机制

5. values 继承于 Collection, EntrySet 和 KeySet 则继承于 Set

6. DeletionEntry 删除指定的元素,fixAfterDeletion 对删除后的树节点进行再平衡,使得 TreeMap 保持红黑树的特性。

7. containsValue(Object) 通过遍历所有元素,来判断是否包含指定的值为 value。因此,效率低。

    public boolean containsValue(Object value) {
for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e))
if (valEquals(value, e.value))
return true;
return false;
}

8. getFirstEntry 返回树中最左下角的元素

    final Entry<K,V> getFirstEntry() {
Entry<K,V> p = root;
if (p != null)
while (p.left != null)
p = p.left;
return p;
}

getLastEntry 返回树中最右下角的元素

    final Entry<K,V> getLastEntry() {
Entry<K,V> p = root;
if (p != null)
while (p.right != null)
p = p.right;
return p;
}

  

9. successor(Entry e)

当 e 为 null 时,返回 null

当 e 有右子节点时,则返回右子节点的最左下角后代节点

当 e 没有右子节点时,返回一个离 e 最近的祖先节点,该祖先节的左孩子也是 e 的祖先节点。

    static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {
if (t == null)
return null;
else if (t.right != null) {
Entry<K,V> p = t.right;
while (p.left != null)
p = p.left;
return p;
} else {
Entry<K,V> p = t.parent;
Entry<K,V> ch = t;
while (p != null && ch == p.right) {
ch = p;
p = p.parent;
}
return p;
}
}

10. prodecessor(Entry e) 和 successor(Entry e) 思路相似。

当 e 为 null 时,返回 null

当 e 有左子节点时,则返回左子节点的最右下角后代节点

当 e 没有左子节点时,返回一个离 e 最近的祖先节点,该祖先节的右孩子也是 e 的祖先节点。

    static <K,V> Entry<K,V> predecessor(Entry<K,V> t) {
if (t == null)
return null;
else if (t.left != null) {
Entry<K,V> p = t.left;
while (p.right != null)
p = p.right;
return p;
} else {
Entry<K,V> p = t.parent;
Entry<K,V> ch = t;
while (p != null && ch == p.left) {
ch = p;
p = p.parent;
}
return p;
}
}

11. get(Object):V 和 getEntry(Object):Entry 的不同点在于,前者返回 V, 而后者返回 Entry。获取的算法一样,因为 get 是基于 getEntry 来实现的。

    public V get(Object key) {
Entry<K,V> p = getEntry(key);
return (p==null ? null : p.value);
}

12. containsKey(Object) 同样也是基于 getEntry 来实现的

    public boolean containsKey(Object key) {
return getEntry(key) != null;
}

13. computeRedLevel(int) ,应用于复制一个 map 到当前为空的 TreeMap 的操作中。复制后的 TreeMap 应该是一棵完全二叉树(complete binary tree),通过将其中满足完美二叉树(perfect binary tree)部分的节点涂黑,则可以简单地实现红黑树的黑属性

    private static int computeRedLevel(int sz) {
int level = 0;
for (int m = sz - 1; m >= 0; m = m / 2 - 1)
level++;
return level;
}

下面是一个完全二叉树的例子,其中满足完美二叉树的只有 0 - 7 个节点,也就是 0 - 2 层。0 - 2 层的节点全部涂黑色,最后一层则全部涂红色。则最方便地满足红黑树的特性。

14. buildFromSorted, 采用递归的思路,先构建后节点的左子树,在构建好节点的右子树,最后和节点组合成一个完整的子树。

15. putAll(Map),

当 TreeMap 没有元素,Map 是一个 sortMap, 并且 Map 的比较器等于 TreeMap 的比较器,则采用 buildFormSorted 来构建 TreeMap。

否则,将 Map 中每个 mapping,通过调用 put(K, V) 来插入 TreeMap 中。

    public void putAll(Map<? extends K, ? extends V> map) {
int mapSize = map.size();
if (size==0 && mapSize!=0 && map instanceof SortedMap) {
Comparator<?> c = ((SortedMap<?,?>)map).comparator();
if (c == comparator || (c != null && c.equals(comparator))) {
++modCount;
try {
buildFromSorted(mapSize, map.entrySet().iterator(),
null, null);
} catch (java.io.IOException cannotHappen) {
} catch (ClassNotFoundException cannotHappen) {
}
return;
}
}
super.putAll(map);
}

16. getEntry, getEntryUsingComparator, getCeilingEntry, getFloorEntry, getHigherEntry, getLowerEntry 都是基于二分查找思路来实现元素操作。

17. put(K, V)

当已存在 key 和 K 相等的 Entry, 则直接更新这个 Entry 的 value 值。

否则,插入新的 Entry ,然后自平衡树结构。

18. remove(Object),删除指定节点,然后自平衡树结构

19. clear(), 将 root 至 null 即可

    public void clear() {
modCount++;
size = 0;
root = null;
}

20.  firstEntry 返回不可变的 Entry , getFirstEntry 则返回可变的 Entry。同样关系的还有:lastEntry 和 getLastEntry,lowerEntry 和 getLowerEntry, higherEntry 和 getHigherEntry。

Jdk 版本: jdk1.8.0_31.jdk

[Java] TreeMap - 源代码学习笔记的更多相关文章

  1. TreeMap - 源代码学习笔记

    TreeMap 实现了 NavigableMap 接口,而NavigableMap 接口继承于 SortedMap接口. 所有本文还会记录 SortedMap 和 NavigableMap 的阅读笔记 ...

  2. [Java] Collections - 源代码学习笔记

    Collection interface 集合接口 1. 在 Collections 体系中,接口 Collection 是根接口 2. 是指一组对象,这些对象被称为 Collection 的元素. ...

  3. [Java] LinkedList / Queue - 源代码学习笔记

    简单地画了下 LinkedList 的继承关系,如下图.只是画了关注的部分,并不是完整的关系图.本博文涉及的是 Queue, Deque, LinkedList 的源代码阅读笔记.关于 List 接口 ...

  4. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  5. Java多线程技术学习笔记(二)

    目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...

  6. Java安全防御学习笔记V1.0

    Java安全防御学习笔记V1.0http://www.docin.com/p-766808938.html

  7. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  8. java之jvm学习笔记三(Class文件检验器)

    java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...

  9. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

随机推荐

  1. ansible小结

    一.Ansible的安装 1.yum源安装 以centos为例,默认在源里没有ansible,不过在fedora epel源里有ansible,配置完epel 源后,可以直接通过yum 进行安装.这里 ...

  2. android - startActivity浅谈

    当执行startActivity(Intent intent, Bundle options)函数的时候,应用程序不是直接呼叫另外一个Activity,而是将intent传进Android框架中.An ...

  3. asp.net 真正实现完全跨域单点登录

    单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. asp.ne ...

  4. Swift - 20 - 字典的基础操作

    //: Playground - noun: a place where people can play import UIKit var dict = [1:"one", 2:& ...

  5. ASP.NET菜鸟之路之实现新闻列表增删改

    背景 我是一个ASP.NET菜鸟,暂时开始学习ASP.NET,在此记录下我个人敲的代码,没有多少参考价值,请看到的盆友们为我点个赞支持我一下,多谢了. 网站介绍 根据视频的例子修改的方法,其中数据不经 ...

  6. Hibernate 性能优化之二级缓存

    二级缓存是一个共享缓存,在二级缓存中存放的数据是共享数据特性     修改不能特别频繁     数据可以公开二级缓存在sessionFactory中,因为sessionFactory本身是线程安全,所 ...

  7. 限制窗口拉伸范围——WM_GETMINMAXINFO

    注意:此方法对CListCtrl的Report模式下的表头绘制有影响,用时需注意测试! 使用OnSizing的改进版 该例程用处为将窗口限制了大小,并且只允许上下拉伸.需要注意的是WM_GETMINM ...

  8. POJ 2411.Mondriaan's Dream 解题报告

    题意: 给出n*m (1≤n.m≤11)的方格棋盘,用1*2的长方形骨牌不重叠地覆盖这个棋盘,求覆盖满的方案数. Solution:                位运算+状态压缩+dp       ...

  9. N3292系列资料之RTC介绍

    N3292系列资料之RTC介绍 1 RTC特性 Ø 拥有时间计数器(秒,分,时)和日历计数器,用来计算时间 Ø 绝对定时功能(秒,分,时,日,月,年) Ø 相对定时功能 Ø 支持12小时/24小时模式 ...

  10. jQuery截取字符串插件区分中英文

    jQuery截取字符串插件区分中英文:截取字符串功能在大量网站都有应用,比如新闻列表这样的功能,因为新闻的标题长途未必都是恰如其分的,所以要根据需要截取指定长度的字符串,下面就分享一个jQuery实现 ...