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. ie8下jquery改变PNG的opacity出现黑边,ie6下png透明解决办法

    目前互联网对于网页效果要求越来越高,不可避免的用到PNG图片,PNG分为几种格 式,PNG8 PNG24 PNG32,其中最常用的,也是显示效果和大小比较适中的则是PNG24,支持半透明,透明,颜色也 ...

  2. hdu 1845

    一看题意就是二分匹配问题,建边是双向的,两个集合都是n个点 这题的图很特殊,每个点都要与三个点相连,在纸上画了六个点的图就感觉此图最大匹配肯定是六,除以2就是原图的匹配了,就感觉这样的图肯定会达到满匹 ...

  3. css强制换行和超出隐藏实现

        一.强制换行1 word-break: break-all; 只对英文起作用,以字母作为换行依据. 2 word-wrap: break-word; 只对英文起作用,以单词作为换行依据. 3 ...

  4. wordpress自动截取文章摘要代码

    想要实现 wordpress 首页显示摘要有几种方法: 第一种,可以在写文章的时侯在需要分割的地方加入<!–more–>标签,但在输出首页摘要的同时,也会使feed只显示摘要,不方便读者阅 ...

  5. Android xml 格式 随笔

    打包的时候Android xml文件会由字符格式(utf-8编码)转换为二进制格式.具体如:http://blog.csdn.net/jiangwei0910410003/article/detail ...

  6. c#如何区分静态只读变量和常量

    常量const 常量就是一个其值永远不会改变的静态字段.常量的值会在编译时自动推算,编译器会在遇到常量时,将其逐个替换为该常量的值.常量可以是C#内建的任何数字类型或枚举类型.声明一个常量的时候必须对 ...

  7. HBase - Phoenix剖析

    1.概述 在<Hadoop-Drill深度剖析>一文当中,给大家介绍了Drill的相关内容,就实时查询来说,Drill基本能够满足要求,同时还可以做一个简单业务上的聚合,如果在使用Hive ...

  8. 【Cocos2d-Js基础教学(5)资源打包工具的使用及资源的异步加载处理】

    TexturePacker是纹理资源打包工具,支持Cocos2dx的游戏资源打包. 如果用过的同学可以直接看下面的资源的异步加载处理 首先为什么用TexturePacker? 1,节省图片资源实际大小 ...

  9. Eclipse+Selenium自动化测试脚本设计V1.0

    Eclipse+Selenium自动化测试脚本设计V1.0 http://www.docin.com/p-803032251.html

  10. Android源码网站

    https://mirrors.tuna.tsinghua.edu.cn/ https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/ https://mirror ...