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. GPRM/GNRMC定位信息的读取与解析

    帧头 UTC时间 状态 纬度 北纬/南纬 经度 东经/西经 速度 $GPRMC hhmmss.sss A/V ddmm.mmmm N/S dddmm.mmmm E/W 节 方位角 UTC日期 磁偏角 ...

  2. mysql 关键字 字段 转义

    insert into tb_gps(imei,lat,lon,speed,dir,alt,atom,`signal`,batt,intime) values('46345435435345','22 ...

  3. SQL语句删除所有表

    ) )     ) )     ) )     ) ) )  TABLE_NAME  CONSTRAINT_NAME  CONSTRAINT_NAME  TABLE_NAME ) ) )  TABLE ...

  4. PHP中ob系列函数整理

    ob,输出缓冲区,是output buffering的简称,而不是output cache.ob用对了,是能对速度有一定的帮助,但是盲目的加上ob函数,只会增加CPU额外的负担. 下面我说说ob的基本 ...

  5. drupal module 自定义

    01 <?php function mytracer_menu() { $items = array(); $items['admin/config/mytracer'] = array( 't ...

  6. 解决mac os x下 tomcat启动报 java.net.BindException: Permission denied <null>:80 错误

    我在mac os x上启动tomcat的时候,报 java.net.BindException: Permission denied <null>:80,java.net.BindExce ...

  7. mongodb_查询操作使用_条件查询、where子句等(转)

    <?php /*  mongodb_查询操作使用_条件查询.where子句等(转并学习)   1.find()/findOne() mongodb数据库的查询操作即使用find()或者findO ...

  8. LoadRunner场景参数文件部分参数说明(我在某银行的整理)

    由于场景中脚本繁多,同时设置60个脚本的“运行时设置”会提示个数限制信息,这时可以考虑通过场景的参数文件配置来批量解决这些事情,主要是提高工作效率. 选中自己保存的controller场景,鼠标右键点 ...

  9. 泊松回归(Poisson Regression)

    本博客已经迁往http://www.kemaswill.com/, 博客园这边也会继续更新, 欢迎关注~ Linear Regression预测的目标\(Y\)是连续值, Logistic Regre ...

  10. BATCH(BAT批处理命令语法)

    bat语法备忘扩展名是bat(在nt/2000/xp/2003下也可以是cmd)的文件就是批处理文件[@more@] bat语法备忘扩展名是bat(在nt/2000/xp/2003下也可以是cmd)的 ...