TreeMap与TreeSet的源码分析
1、TreeMap源码
1、属性部分:
private final Comparator<? super K> comparator;//比较器 private transient Entry<K,V> root;//根节点 private transient int size = 0;//大小 private transient int modCount = 0;//结构修改次数 定义一个静态内部对象用以存储:
static final class Entry<K,V> implements Map.Entry<K,V> {
K key;
V value;
Entry<K,V> left;
Entry<K,V> right;
Entry<K,V> parent;
boolean color = BLACK;
...
重写了equals、hashCode、toString方法等
2、构造器部分:
public TreeMap() {//无参构造
comparator = null;
}
public TreeMap(Comparator<? super K> comparator) {//带比较器构造
this.comparator = comparator;
}
public TreeMap(Map<? extends K, ? extends V> m)
public TreeMap(SortedMap<K, ? extends V> m)
3、put方法:
public V put(K key, V value) {
Entry<K,V> t = root;
//如果根节点为空,设置该元素为根节点;
if (t == null) {
compare(key, key); // type (and possibly null) check
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator;//comparator来自哪?构造器中;
//如果传入对象自带比较器:
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
//无自带比较器,使用默认的比较机制:
else {
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);//注意key是实现比较器的对象
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
注意:
<1>:首先,如果想往TreeMap中存放Entry<K,V>,那么其K必须是实现compareTo方法的,那么K所对应的类需要implements comparable接口。当然常用类中已经重写了这个方法,所以我们可以直接使用:TreeMap.put(int a,String b)等;
<2>:TreeMap是基于红黑树的数据结构,TreeMap中判断新入元素的存储位置时,只需要通过compareTo方法判断两个对象的Key是否相同:相同,则更新Value,返回旧值Value;不同,则插在左或右子节点上,不同于HashMap通过Key的hashCode判断存储位置,所以即使在TreeMap中没有hashCode和equals方法的重写,对于put也没有影响。
<3>:put入新节点后,TreeMap需要调整整个红黑树的结构。后续学习......;
2、TreeSet的add源码
public boolean add(E e) { return m.put(e, PRESENT)==null; }
看到add只需要接收一个参数e,m是一个 private transient NavigableMap<E,Object> m; ,接口,其实现类是TreeMap,因此知道,TreeSet的add通过调用TreeMap的put方法实现添加节点操作,但是由于add只接收一个形参e,故TreeSet生成了一个PRESENT以构成<K,V>的形式,PRESENT是 private static final Object PRESENT = new Object(); 完全是用来凑得嘛。
但是一定要注意:TreeMap的put中当通过comparedTo判断两个节点的Key相等时,会更新Value。而TreeSet的Value并没有什么作用,故可Key还是原来的Key,并没有发生改变。
总结:如果要插入新元素到TreeMap或TreeSet中:
1、TreeMap中若newKey.compareTo(oldkey)返回值是0,那么Key不变,更新Value的值为newValue,返回oldValue。
2、TreeSet中,简单可以理解为不更新(因为我们只用Key)。
实例:
public class C1 implements Comparable {
String attr1="attr";
static int attr2=2;//注意static
public C1(String attr1,int attr2){
this.attr1=attr1;
this.attr2=attr2;
}
public String getAttr1() {
return attr1;
}
public void setAttr1(String attr1) {
this.attr1 = attr1;
}
public int getAttr2() {
return attr2;
}
public void setAttr2(int attr2) {
this.attr2 = attr2;
}
@Override
public int compareTo(Object that) {
// return ((C1)that).attr2-((C1)this).getAttr2();
return 0;
}
public String toString(){return "attr1="+attr1+",attr2="+attr2+";";}
public boolean equals(Object that){
return attr1==((C1)that).getAttr1();
}
public int hashCode(){return attr2;}
public static void main(String[] args) {
Set set=new TreeSet();
C1 c1=new C1("sttr",4);
set.add(c1);
C1 c2=new C1("sttr",5);
set.add(c2);
set.add(new C1("sttr",5));
set.add(new C1("sttr",3));
set.add(new C1("sttr2",2));
System.out.println(set);
}
}
[attr1=sttr,attr2=2;]
//为什么是2?注意attr2是static的,最后一个new C1(..)会改变该所有对象的attr2值。TreeSet没有不会更新Key(就是这个对象new C1(..))
结果1
[attr1=sttr,attr2=4;]
//正常,没有更新
结果2
//compareTo第一行,attr2不带static
[attr1=sttr,attr2=5;, attr1=sttr,attr2=4;, attr1=sttr,attr2=3;, attr1=sttr2,attr2=2;]
结果3
//compareTo第一行,attr2带static [attr1=sttr,attr2=2;]
结果4
TreeMap与TreeSet的源码分析的更多相关文章
- TreeMap实现原理及源码分析之JDK8
转载 Java 集合系列12之 TreeMap详细介绍(源码解析)和使用示例 一.TreeMap 简单介绍 什么是Map? 在数组中我们通过数组下标来对数组内容进行索引的,而在Map中我们通过对象来对 ...
- TreeMap实现原理及源码分析
TreeMap是一个有序的key-value集合,基于红黑树(Red-Black tree)实现.该映射根据其键的自然顺序进行排序,或者根据创建时提供的Comparator进行排序. 对于TreeMa ...
- Java集合源码分析(六)TreeSet<E>
TreeSet简介 TreeSet 是一个有序的集合,它的作用是提供有序的Set集合.它继承于AbstractSet抽象类,实现了NavigableSet<E>, Cloneable, j ...
- 死磕 java集合之TreeSet源码分析
问题 (1)TreeSet真的是使用TreeMap来存储元素的吗? (2)TreeSet是有序的吗? (3)TreeSet和LinkedHashSet有何不同? 简介 TreeSet底层是采用Tree ...
- 集合之TreeSet(含JDK1.8源码分析)
一.前言 前面分析了Set接口下的hashSet和linkedHashSet,下面接着来看treeSet,treeSet的底层实现是基于treeMap的. 四个关注点在treeSet上的答案 二.tr ...
- Java集合源码分析(十)——TreeSet
简介 TreeSet就是一个集合,里面不能有重复的元素,但是元素是有序的. TreeSet其实就是调用了TreeMap实现的,所以,它也不是线程安全的.可以实现自然排序或者根据传入的Comparato ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- 【集合框架】JDK1.8源码分析之TreeMap(五)
一.前言 当我们需要把插入的元素进行排序的时候,就是时候考虑TreeMap了,从名字上来看,TreeMap肯定是和树是脱不了干系的,它是一个排序了的Map,下面我们来着重分析其源码,理解其底层如何实现 ...
- TreeMap 源码分析
简介 TreeMap最早出现在JDK 1.2中,是 Java 集合框架中比较重要一个的实现.TreeMap 底层基于红黑树实现,可保证在log(n)时间复杂度内完成 containsKey.get.p ...
随机推荐
- java实现 TCP通信
//服务端import com.hl.bluetooth.util.CRC16; import com.hl.bluetooth.util.FrameCheckFailedException; imp ...
- docker为什么会出现
痛点 环境不同所引发的问题 一款产品从开发到上线,一般都会有开发环境,测试环境,运行环境. 如果有一个环境中某个软件或者依赖版本不同了,可能产品就会出现一些错误,甚至无法运行.比如开发人员在windo ...
- 二,配置jdk,安装tomcat.以及tomcat项目的发布
1.jdk配置 一.环境准备 Windows10 jdk-9.0.1 二.下载并安装JDK 选择一个适合自己的JDK版本下载并安装即可,具体流程不详述. 三.环境变量配置 1.右键桌面上"我 ...
- Wi-Fi DFS与TPC介绍
DFS与TPC是wifi认证的其中一项测试内容,如果不需要DFS功能,可以不进行测试,但是某些属于DFS频段的wifi信道则不允许使用. 1. 什么是WIFI Auto DFS? 通俗的说就是:躲雷达 ...
- jmeter压测tcp协议接口:java.net.SocketException: Software caused connection abort: socket write error
tcp接口,试压过程中,部分请求报如下错误: java.net.SocketException: Software caused connection abort: socket write erro ...
- Java8新特性系列-默认方法
Java8 Interface Default and Static Methods 原文连接:Java8新特性系列-默认方法 – 微爱博客 在 Java 8 之前,接口只能有公共抽象方法. 如果不强 ...
- 学习Spring5必知必会(5)~Spring AOP
一.学习 AOP 思想的准备工作: 1.横切面关注点 在开发中,为了给业务方法中增加日志记录,权限检查,事务控制等功能,此时我们需要在修改业务方法内添加这些零散的功能代码(横切面关注点). 这些零散存 ...
- 教你快速区分传统报表和商业智能BI
很多人分不清楚,传统报表和商业智能BI之间的区别?有些人认为,BI就是做报表的,其实不然,报表只是BI的一部分,报表是关于过去和现状的展示,而BI是关于如何通过分析数据,帮助决策者找到改变和提高的方案 ...
- Smartbi集成性怎么样,是否方便与已有的Web应用集成?
Smartbi产品具有强大的集成能力,它采用纯JAVA开发,支持J2EE系统的嵌入式部署,它对外提 供所有功能的API访问接口,可以实现灵活的控制,能够方便无缝与已有的Web应用进行集成. 支持丰富 ...
- idea常用快捷键及配置
目录 常用快捷键 常用配置 配置修改项 版本2019.1.3,配置.破解插件见网盘 2020.3.4 链接:https://pan.baidu.com/s/1WHsS8-yvHGf1iRopLbKIu ...