TreeSet与TreeMap浅解
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浅解的更多相关文章
- List根据某字段去重,以及compareTo 浅解
原文链接:https://blog.csdn.net/qq_35788725/article/details/82259013 Collections.sort可对集合进行排序 根据List里面某个字 ...
- Java 集合类 TreeSet、TreeMap
TreeMap和TreeSet的异同: 相同点: TreeMap和TreeSet都是有序的集合,也就是说他们存储的值都是拍好序的. TreeMap和TreeSet都是非同步集合,因此他们不能在多线程之 ...
- 第40讲:Set、Map、TreeSet、TreeMap操作代码实战
今天来看下set map的操作,让我们从代码出发 val data = mutable.Set.empty[Int] data ++= List(1,2,3)//在空set上加入列表 data += ...
- TreeSet和TreeMap的输出
如果加入TreeSet和TreeMap的元素没有实现comprable中的compareTo()方法,那么会报错"treeset cannot be cast to java.lang.Co ...
- 从最大似然到EM算法浅解
从最大似然到EM算法浅解 zouxy09@qq.com http://blog.csdn.net/zouxy09 机器学习十大算法之中的一个:EM算法.能评得上十大之中的一个,让人听起来认为挺NB的. ...
- Java容器-引用数据类型排序+TreeSet、TreeMap底层实现
目录 1.冒泡排序的实现 2.比较接口(普通数据类型.引用数据类型) 普通数据类型:冒泡排序 引用数据类型:包装类(Integer.String.Character.Date) 自定义类型:实体类:i ...
- B树和TreeSet与TreeMap
1. 此前二叉搜索树相关的内容我们均假设可以把整个数据结构存储在计算机的内存中,但是如果数据量过大时,必须把数据结构放在磁盘上,导致大O模型不在适用.目前计算机处理器每秒至少可以执行5亿条指令,磁盘访 ...
- JDK学习---深入理解Comparator、TreeSet、TreeMap为什么可以排序
我本来打算仔细的去分析分析TreeSet和TreeMap排序规则,并且从底层实现和数据结构入手.当我去读完底层源码以后,我感觉我就的目标定的太大了,单单就是数据结构就够我自己写很久了,因此我决定先易后 ...
- 面试-1-C#浅解
面试-1 C#浅解众所周知c#是微软推出的一款完全没面向对象的编程语言,那么对象是什么?在现实生活中人们一提到对象首先想到的就是“情侣”!但是在我们的程序中对象是什么? 在程序中个能够区别于其他事 ...
随机推荐
- android手机两种方式获取IP地址
1.使用WIFI 首先设置用户权限 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"& ...
- Naked Search in service
public List<TplRelease> searchTplReleaseById(TplRelease tr)throws Exception{ DBOperator dbo = ...
- IntelliJ IDEA + Maven创建Java Web项目
1. Maven简介 相对于传统的项目,Maven 下管理和构建的项目真的非常好用和简单,所以这里也强调下,尽量使用此类工具进行项目构建, 它可以管理项目的整个生命周期. 可以通过其命令做所有相关的工 ...
- Codeforces Round #382 (Div. 2)B. Urbanization 贪心
B. Urbanization 题目链接 http://codeforces.com/contest/735/problem/B 题面 Local authorities have heard a l ...
- HTTP - GET和POST的区别
网上有很多文章介绍这两种HTTP请求的区别,我也不懂,主要还是看了一些文章,在这里写下一些笔记. 语义不同 在HTTP协议中,最初规定GET是用来查询或者获取资料,只读,POST用于修改数据,可写.因 ...
- Delphi Android程序启动过程
Delphi的Android程序是原生的程序,也就是NativeActivity.那么就需要先看一下NativeActivity的原理, 在AndroidManifest.xml文件里面指定入口act ...
- java单例之enum实现方式
传统的两私有一公开(私有构造方法.私有静态实例(懒实例化/直接实例化).公开的静态获取方法)涉及线程安全问题(即使有多重检查锁也可以通过反射破坏单例), 目前最为安全的实现单例的方法是通过内部静态en ...
- CYQ学习教程
http://www.cyqdata.com/cyqdata/article-detail-413
- Strategy策略设计模式
1.策略模式和状态模式的区别和联系(本部分转载自:http://letscoding.cn/java%E4%B8%AD%EF%BC%8C%E7%8A%B6%E6%80%81%E6%A8%A1%E5%B ...
- 理解RxJava:(二)Operator,Operator
在第一部分,我讲解了RxJava的基本结构,也介绍了map()操作.然而,我能理解你仍旧不会选择使用Rxjava--你仍然还有很多东西没有学到.但是这个情况将很快得到改变.Rxjava一大部分的能力是 ...



