基于jdk1.8

TreeMap第一个想到的就是有序,当然也不是线程安全

TreeMap实现NavigableMap接口,说明支持一系列的导航方法

一、构造方法

    public TreeMap() {
comparator = null;
}
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
public TreeMap(Map<? extends K, ? extends V> m) {
comparator = null;
putAll(m);
}
public TreeMap(SortedMap<K, ? extends V> m) {
comparator = m.comparator();
try {
buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
} catch (java.io.IOException cannotHappen) {
} catch (ClassNotFoundException cannotHappen) {
}
}
看到这4个构造方法就说明TreeMap是比较注重排序的,comparator即排序规则,不指定是按key类的自有排序规则进行排序后面具体看,其它按指定规则排序

二、put方法
通过put方法,我们就能看出基本数据结构和内存结构了,包括排序等等,这是一个信息量最大的方法

public V put(K key, V value) {
Entry<K,V> t = root; //Entry类一看就知道了 红黑树
if (t == null) {
//这里是空树,比较同一个key看似没什么用,实际就一个用检查key是否为null,因此无论什么场景第一个put的key不能null
compare(key, key); // type (and possibly null) check root = new Entry<>(key, value, null);//第一个节点设置root
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator;
if (cpr != null) { //有排序规则 这个if是按排序规则比较,左右挂节点
do {
parent = t;
cmp = cpr.compare(key, t.key); //注意能允许key为null的,只要指定的排序规则支持就可以
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value); //key相同直接覆盖
} while (t != null);
}
else { //无排序规则
if (key == null) //无排序规则时key不能为null
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key; //这里需要注意,没指定排序规则时key的类就必须实现Comparable排序接口,否则转换报错
do {
parent = t;
cmp = k.compareTo(t.key); //按key的实际类排序方案进行比较挂节点
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
//前面的if else找到了当前key需要挂的父节点,cmp决定了挂的左右
Entry<K,V> e = new Entry<>(key, value, parent); //创建当前插入元素的节点
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e); //这个方法就不详细说了,插入节点后的红黑树修复方法,详细可单独学习红黑树
size++;
modCount++;
return null;
}
通过put方法知道,TreeMap数据结构只有红黑树,没有其它了,也不存在hash的问题

三、get方法

final Entry<K,V> getEntry(Object key) {
// Offload comparator-based version for sake of performance
if (comparator != null) //有排序规则 详细看
return getEntryUsingComparator(key);
if (key == null) //无排序规则key不能为null
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
Entry<K,V> p = root;
while (p != null) { //红黑树节点查找没什么说的
int cmp = k.compareTo(p.key);
if (cmp < 0)
p = p.left;
else if (cmp > 0)
p = p.right;
else
return p;
}
return null;
} //有排序规则时查找节点的方法 实际没什么区别,只是compare比较用了指定的排序规则而已
final Entry<K,V> getEntryUsingComparator(Object key) {
@SuppressWarnings("unchecked")
K k = (K) key;
Comparator<? super K> cpr = comparator;
if (cpr != null) {
Entry<K,V> p = root;
while (p != null) {
int cmp = cpr.compare(k, p.key);
if (cmp < 0)
p = p.left;
else if (cmp > 0)
p = p.right;
else
return p;
}
}
return null;
}

四、其它
TreeMap整体看下来,主要就是红黑树的书法实现,其它没用到,至于remove等方法以及导航方法,和迭代器就不多说了。
so 主要就是学习红黑树

TreeMap 原理的更多相关文章

  1. TreeMap原理实现及常用方法

    目录 一. TreeMap概述 二. 红黑树回顾 三. TreeMap构造 四. put方法 五. get 方法 六. remove方法 七. 遍历 八. 总结 前面我们分别讲了Map接口的两个实现类 ...

  2. jdk TreeMap工作原理分析

    TreeMap是jdk中基于红黑树的一种map实现.HashMap底层是使用链表法解决冲突的哈希表,LinkedHashMap继承自HashMap,内部同样也是使用链表法解决冲突的哈希表,但是额外添加 ...

  3. Java集合 HashSet的原理及常用方法

    目录 一. HashSet概述 二. HashSet构造 三. add方法 四. remove方法 五. 遍历 六. 合计合计 先看一下LinkedHashSet 在看一下TreeSet 七. 总结 ...

  4. java源码 -- TreeMap

    简介 TreeMap 是一个有序的key-value集合,它是通过红黑树实现的.TreeMap 继承于AbstractMap,所以它是一个Map,即一个key-value集合.TreeMap 实现了N ...

  5. Hadoop 之面试题

    颜色区别: 蓝色:hive,橙色:Hbase.黑色hadoop 请简述hadoop怎样实现二级排序. 你认为用Java,Streaming,pipe 方式开发map/reduce,各有哪些优缺点: 6 ...

  6. 给jdk写注释系列之jdk1.6容器(8)-TreeSet&NavigableMap&NavigableSet源码解析

    TreeSet是一个有序的Set集合. 既然是有序,那么它是靠什么来维持顺序的呢,回忆一下TreeMap中是怎么比较两个key大小的,是通过一个比较器Comparator对不对,不过遗憾的是,今天仍然 ...

  7. Java提高十七:TreeSet 深入分析

    前一篇我们分析了TreeMap,接下来我们分析TreeSet,比较有意思的地方是,似乎有Map和Set的地方,Set几乎都成了Map的一个马甲.此话怎讲呢?在前面一篇讨论HashMap和HashSet ...

  8. 《OD面试》Java面试题整理

    一.面试考察点 1 主语言本身 2 数据库 3 算法 4 Spring/SpringMVC/MyBatis 5 项目经验 1)项目涉及到的技术点深挖: (1)考察候选人技术深度  (2)看候选人遇到问 ...

  9. Java并发—同步容器和并发容器

    简述同步容器与并发容器 在Java并发编程中,经常听到同步容器.并发容器之说,那什么是同步容器与并发容器呢?同步容器可以简单地理解为通过synchronized来实现同步的容器,比如Vector.Ha ...

随机推荐

  1. centos安装mongodb 4.x及配置用户名密码(官方推荐的方式)

    安装mongodb 先在本地用记事本做一个这样的文件(命名为:mongodb-org-4.0.repo): [mongodb-org-4.0] name=MongoDB Repository base ...

  2. 史上最全的用Python操控手机APP攻略!建议收藏!

    ​最近经常看到用Python操作手机APP的项目,例如抖音.闲鱼之类的,看完后发现这些项目无一例外需要部署ADB环境.至于什么是ADB,很多大神都讲过,只是写得比较专业,我等菜鸟看完还是云里雾里. ​ ...

  3. plsql基础练习题

    1.键盘输入一个年份,判断是否是闰年; (能被4整除而不能被100整除或者能被100和400同时整除,满足其一即可); 方法1 declare v_year number(4):=&请输入一个 ...

  4. ARM64 的 memcpy 优化与实现

    参考:https://www.byteisland.com/arm64-%E7%9A%84-memcpy-%E6%B1%87%E7%BC%96%E5%88%86%E6%9E%90/ libc/stri ...

  5. Java泛型类型擦除与运行时类型获取

    Java的泛型大家都知道是类型擦除的方式实现的,“编译器会进行泛型擦除”是一个常识了(实际擦除的是参数和自变量的类型).“类型擦除” 并非像许多开发者认为的那样,在 <..> 符号内的东西 ...

  6. 最全各种系统版本的XPosed框架资料下载整理

    由于XPosed在不同安卓系统版本中对应的版本不同,给很多新手造成极大困扰,本文作者经过几番努力,给大家整理了各个版本对应的xposed框架版本以及相关资料,并附上相关下载链接,希望对大伙有所帮助. ...

  7. 二级目录下的运行main.py,找不到上级目录的解决方法

    import os, sys sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

  8. .net core 后台如何生成html字符串到前台_后台html字符串在前台显示编码状态

    1-后台生成html字符串的方法一般是: this.ViewData.Add("CURRENCY_SYMBOLS", new HtmlString(JsonHelper.Conve ...

  9. 关于ScriptManager.RegisterStartupScript 摘录

    //ScriptManager.RegisterStartupScript 方法 (Control, Type, String, String, Boolean) public static void ...

  10. VMWare虚拟机应用介绍

    目录 一:VMWare简介 二:VMWare启动第一个虚拟机 一:VMWare简介   VMWare虚拟机软件是一个"虚拟PC"软件,它使你可以在一台机器上同时运行二个或更多Win ...