TreeSet与TreeMap的关系:

1.TreeSet 实际上就是用TreeMap来组织数据的,因为在TreeSet中保存了一个NavigableMap<e,Object>接口实例变量,而该接口的实现类就是TreeMap

2.TreeSet与TreeMap都是用二叉树的数据结构来存储数据

3.TreeSet和TreeMap中保存的数据除了Integer和String等有默认顺序的类型外的自定义类型都需要实现Comparable接口并重写compareTo()方法。

TreeSet和TreeMap添加数据:

TreeSet的add方法会调用TreeMap的put方法

TreeMap的put()方法的实现,

public V put(K key, V value) {
Entry<K,V> t = root;
//判断二叉树中是否存在根节点如果存在则床建根节点
if (t == null) {
root = new Entry<K,V>(key, value, null);//创建根节点
size = 1;//将该集合的元素个数设为1
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;//声明父节点
Comparator<? super K> cpr = comparator;//创建比较器
if (cpr != null) {//该集合有自定义比较器
do {
parent = t;//将父节点设为t (第一次t为根节点)
cmp = cpr.compare(key, t.key);//将根节点的key与参数中的key进行比较
if (cmp < 0)//key<t.key
t = t.left;
else if (cmp > 0)//key>t.key
t = t.right;
else
return t.setValue(value);//key==t.key
} while (t != null);
}
else {//该集合没有自定义比较器
if (key == null)
throw new NullPointerException();
Comparable<? super K> k = (Comparable<? super K>) key;//参数使用类型的比较器
do {
parent = t;//将父节点设为t (第一次t为根节点)
cmp = k.compareTo(t.key);//将根节点的key与参数中的key进行比较
if (cmp < 0)//key<t.key
t = t.left;
else if (cmp > 0)//key>t.key
t = t.right;
else
return t.setValue(value);;//key==t.key
} while (t != null);
}
Entry<K,V> e = new Entry<K,V>(key, value, parent);//将传入的参数封装为集合元素
if (cmp < 0)//e<parent
parent.left = e;
else
//e>parent
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}

下面用图形的方式来进行一个比较直观的显示

第一次赋值:

将该值作为根节点存放

第二次赋值:

值小于根节点

值大于根节点

第三次赋值

假设赋值为3其先和根节点“2”进行比较其大于“2”尝试将其赋值为根节点“2”的右子节点但发现其已有值,所以查找2的右子节点“4”与其进行比较发现其小于“4”所以赋值结果如图所示:

以此类推所以其最终的数据结构类似于下图所示的到树状结构

TreeSet和TreeMap获取值

其获取值和赋值类似也是从根节点开始与其子节点逐一对比直至找到要查序的元素

源码:

getEntry(key)方法源码:

final Entry<K,V> getEntry(Object key) {

        if (comparator != null)
//集合存在自定义比较器
return getEntryUsingComparator(key);
if (key == null)
throw new NullPointerException();
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;如果k与该节点的key比较返回值=0(返回0代表其相等)则返回该节点
}
return null;
}

getEntryUsingComparator(key)源码:

//使用自定义比较器进行比较遍历
final Entry<K,V> getEntryUsingComparator(Object key) {
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;
}

 

Treeset和TreeMap的排序

其排序会按照其二叉树的层级关系从最左侧的叶级节点开始找其父节点在查找其父节点的右子节点若其父节点的右子节点下还有子节点则遍历该右节点直至找到该右节点下最左边的叶级节点当期父节点遍历完成之后则以同样的方法遍历其父节点的父节点以此类推直至该二叉树遍历完毕

如图所示:

TreeSet与TreeMap浅解的更多相关文章

  1. List根据某字段去重,以及compareTo 浅解

    原文链接:https://blog.csdn.net/qq_35788725/article/details/82259013 Collections.sort可对集合进行排序 根据List里面某个字 ...

  2. Java 集合类 TreeSet、TreeMap

    TreeMap和TreeSet的异同: 相同点: TreeMap和TreeSet都是有序的集合,也就是说他们存储的值都是拍好序的. TreeMap和TreeSet都是非同步集合,因此他们不能在多线程之 ...

  3. 第40讲:Set、Map、TreeSet、TreeMap操作代码实战

    今天来看下set map的操作,让我们从代码出发 val data = mutable.Set.empty[Int] data ++= List(1,2,3)//在空set上加入列表 data += ...

  4. TreeSet和TreeMap的输出

    如果加入TreeSet和TreeMap的元素没有实现comprable中的compareTo()方法,那么会报错"treeset cannot be cast to java.lang.Co ...

  5. 从最大似然到EM算法浅解

    从最大似然到EM算法浅解 zouxy09@qq.com http://blog.csdn.net/zouxy09 机器学习十大算法之中的一个:EM算法.能评得上十大之中的一个,让人听起来认为挺NB的. ...

  6. Java容器-引用数据类型排序+TreeSet、TreeMap底层实现

    目录 1.冒泡排序的实现 2.比较接口(普通数据类型.引用数据类型) 普通数据类型:冒泡排序 引用数据类型:包装类(Integer.String.Character.Date) 自定义类型:实体类:i ...

  7. B树和TreeSet与TreeMap

    1. 此前二叉搜索树相关的内容我们均假设可以把整个数据结构存储在计算机的内存中,但是如果数据量过大时,必须把数据结构放在磁盘上,导致大O模型不在适用.目前计算机处理器每秒至少可以执行5亿条指令,磁盘访 ...

  8. JDK学习---深入理解Comparator、TreeSet、TreeMap为什么可以排序

    我本来打算仔细的去分析分析TreeSet和TreeMap排序规则,并且从底层实现和数据结构入手.当我去读完底层源码以后,我感觉我就的目标定的太大了,单单就是数据结构就够我自己写很久了,因此我决定先易后 ...

  9. 面试-1-C#浅解

    面试-1   C#浅解众所周知c#是微软推出的一款完全没面向对象的编程语言,那么对象是什么?在现实生活中人们一提到对象首先想到的就是“情侣”!但是在我们的程序中对象是什么? 在程序中个能够区别于其他事 ...

随机推荐

  1. Maven Nexus Setup tutorial

    Technorati 标签: maven,nexus 1. download the Nexus from website for free version: 2. Run the Command p ...

  2. DataGridView隔行显示不同的颜色

      如果该dataGridView是跟数据库绑定的,则可以触发DataBindingComplete事件:  1private   void   dataGridView1_DataBindingCo ...

  3. AYUI4.X即将发布

    AYUI里程碑故事: AYUI 1.x系列:   面向源码的方式开发,客户只有源码才能开发,客户端对接ayui,很不方便,相比上个版本,提供了一些元老控件,文件夹结构比较零散 AYUI 2.x系列: ...

  4. [aaronyang]WPF4.5 - AyTabControlBase样式分享,绝对好看

    样式代码如下: 对于博客园将文章移除首页的做法:我就迁移了.文章已经迁移:http://www.ayjs.net/post/75.html 由于例子比较简单,你只要指定Style即可,难点,透明区域的 ...

  5. python数据结构之图深度优先和广度优先

    首先有一个概念:回溯 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法 ...

  6. db2 ha create dependency failed 解决

    db2diag.log 2014-10-16-23.27.55.009490-240 E31979E444 LEVEL: ErrorPID : 6651 TID : 140508206864160 P ...

  7. Swift中的Void类型与空元祖表达式

    可能有不少Swift开发者会忽略这么一个细节:在Swift中,Void类型其实是一个别名类型,而其真正的类型为(),即一个空元祖(empty tuple)! 这种语言特性给Swift带来了一些比较方便 ...

  8. .net微信公众号开发——模板消息

    作者:王先荣    本文介绍微信公众号中的模板消息,包括以下内容:(1)TemplateMessage类简介:(2)设置所属行业:(3)获得模板id:(4)发送模板消息:(5)接收推送模板消息发送结果 ...

  9. GitHub上排名前100的Android开源库介绍(来自github)

    本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍,至于排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果,然后过滤了 ...

  10. struts2:数据校验,通过Action中的validate()方法实现校验(续:多业务方法时的不同验证处理)

    前文:struts2:数据校验,通过Action中的validate()方法实现校验,图解 如果定义的Action中存在多个逻辑处理方法,且不同的处理逻辑可能需要不同的校验规则,在这种情况下,就需要通 ...