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. 通过apt-get安装nvidia驱动

    标签:NVIDIA Driver apt 早前安装的NVIDIA显卡驱动在启动X Server的时候提示版本太新了,要求必须使用340.96的,而新的驱动都到了367 https://wiki.deb ...

  2. libev代码

    就是贴上来: ev.c: /* * libev event processing core, watcher management */ /* this big block deduces confi ...

  3. dubbo 管理控制台 的安装 dubbo-admin

    按照官方文档来,只是官方文档中提供的war包无法下载,我的环境至少是这样,不知道其他网络环境是否OK. war包下载地址:链接: http://pan.baidu.com/s/1i32fs7j 密码: ...

  4. mysql设置连接超时时间参数:wait_timeout

    [root@ ~]# mysql -h 192.168.0.* -uroot -pEnter password: Welcome to the MySQL monitor. Commands end ...

  5. 解决企业In-House安装APP需HTTPS支持的问题(转载)

    同事写的一篇文章,感觉不错,转过来. 解决企业In-House安装APP需HTTPS支持的问题 问题背景: 能否通过应用服务器发布企业应用: 解决iOS7.1后,发布地址必须为HTTPS服务器. 写作 ...

  6. Openvswitch原理与代码分析(3): openvswitch内核模块的加载

      上一节我们讲了ovs-vswitchd,其中虚拟网桥初始化的时候,对调用内核模块来添加虚拟网卡.   我们从openvswitch内核模块的加载过程,来看这个过程.   在datapath/dat ...

  7. 【Cocos2d-Js基础教学(4)cocostudio在cocos2dx-Js中的使用】

    首先我们打开官方网站www.cocos2d-x.org,下载我们安装最新的cocostudio(cocos). 简介: Cocos Studio升级为cocos.更优秀的产品.更优质的服务.游戏开发一 ...

  8. searchableselect不支持onchange的问题

    1.找到jquery.searchableSelect.js 2.找到selectItem函数 修改里面的方法,加入自定义你要回调的函数 selectItem: function(item){ //L ...

  9. MySQL降权:MySQL以Guests帐户启动设置方法

    MySQL安装到Windows上,默认是以SYSTEM权限运行,如下图: SYSTEM是超级管理员.不是必须,不推荐用此权限运行任何程序. 本文将演示如何在GUEST帐户下运行MySQL. 第一步:建 ...

  10. iOS开发-pod install 出错 The dependency `AFNetworking (~> 2.6.0)` is not used in any concrete target.

    低版本的cocoapods的Podfile文件pod install可以正常运行 platform :ios, '8.0' pod 'AFNetworking' 高版本的cocoapods的Podfi ...