java源码分析之TreeMap基础篇

java源码分析之TreeMap深入篇 TreeMap有Values、EntrySet、KeySet、PrivateEntryIterator、EntryIterator、ValueIterator、KeyIterator、DescendingKeyIterator、NavigableSubMap、AscendingSubMap、DescendingSubMap、SubMap、Entry共十三个内部类。Entry是在TreeMap中用于 阅读详情

常见的数据结构有数组、链表,还有一种结构也很常见,那就是树。前面介绍的集合类有基于数组的ArrayList,有基于链表的LinkedList,还有链表和数组结合的HashMap,今天介绍基于树的TreeMap。

     TreeMap基于红黑树(点击查看树、红黑树相关内容)实现。查看“键”或“键值对”时,它们会被排序(次序由Comparable或Comparator决定)。TreeMap的特点在于,所得到的结果是经过排序的。TreeMap是唯一的带有subMap()方法的Map,它可以返回一个子树。 

     在介绍TreeMap前先介绍Comparable和Comparator接口。 

     Comparable接口:

1 public interface Comparable<T> {
2     public int compareTo(T o);
3 }

     Comparable接口支持泛型,只有一个方法,该方法返回负数、零、正数分别表示当前对象“小于”、“等于”、“大于”传入对象o。

     Comparamtor接口:

1 public interface Comparator<T> {
2 int compare(T o1, T o2);
3 boolean equals(Object obj);
4 }

     compare(T o1,T o2)方法比较o1和o2两个对象,o1“大于”o2,返回正数,相等返回零,“小于”返回负数。

     equals(Object obj)返回true的唯一情况是obj也是一个比较器(Comparator)并且比较结果和此比较器的结果的大小次序是一致的。即comp1.equals(comp2)意味着sgn(comp1.compare(o1, * o2))==sgn(comp2.compare(o1, o2))。

     补充:符号sgn(expression)表示数学上的signum函数,该函数根据expression的值是负数、零或正数,分别返回-1、0或1。

     小结一下,实现Comparable结构的类可以和其他对象进行比较,即实现Comparable可以进行比较的类。而实现Comparator接口的类是比较器,用于比较两个对象的大小。

     下面正式分析TreeMap的源码。

     既然TreeMap底层使用的是树结构,那么必然有表示节点的对象。下面先看TreeMap中表示节点的内部类Entry。

复制代码
 1 static final class Entry<K,V> implements Map.Entry<K,V> {
 2 // 键值对的“键”
 3 K key;
 4 // 键值对的“值”
 5     V value;
 6     // 左孩子
 7     Entry<K,V> left = null;
 8     // 右孩子
 9     Entry<K,V> right = null;
10     // 父节点
11     Entry<K,V> parent;
12     // 红黑树的节点表示颜色的属性
13     boolean color = BLACK;
14     /**
15      * 根据给定的键、值、父节点构造一个节点,颜色为默认的黑色
16      */
17     Entry(K key, V value, Entry<K,V> parent) {
18         this.key = key;
19         this.value = value;
20         this.parent = parent;
21     }
22     // 获取节点的key
23     public K getKey() {
24         return key;
25     }
26     // 获取节点的value
27     public V getValue() {
28         return value;
29     }
30     /**
31      * 修改并返回当前节点的value
32      */
33     public V setValue(V value) {
34         V oldValue = this.value;
35         this.value = value;
36         return oldValue;
37     }
38     // 判断节点相等的方法(两个节点为同一类型且key值和value值都相等时两个节点相等)
39     public boolean equals(Object o) {
40         if (!(o instanceof Map.Entry))
41             return false;
42         Map.Entry<?,?> e = (Map.Entry<?,?>)o;
43         return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
44     }
45     // 节点的哈希值计算方法
46     public int hashCode() {
47         int keyHash = (key==null ? 0 : key.hashCode());
48         int valueHash = (value==null ? 0 : value.hashCode());
49         return keyHash ^ valueHash;
50     }
51     public String toString() {
52         return key + "=" + value;
53     }
54 }
复制代码

    上面的Entry类比较简单,实现了树节点的必要内容,提供了hashCode方法等。下面看TreeMap类的定义。

1 public class TreeMap<K,V>
2     extends AbstractMap<K,V>
3     implements NavigableMap<K,V>, Cloneable, java.io.Serializable

     上面只有一个接口需要说明,那就是NavigableMap接口。

     NavigableMap接口扩展的SortedMap,具有了针对给定搜索目标返回最接近匹配项的导航方法。方法lowerEntry、floorEntry、ceilingEntry和higherEntry分别返回与小于、小于等于、大于等于、大于给定键的键关联的Map.Entry对象,如果不存在这样的键,则返回null。类似地,方法lowerKey、floorKey、ceilingKey和higherKey只返回关联的键。所有这些方法是为查找条目而不是遍历条目而设计的(后面会逐个介绍这些方法)。

     下面是TreeMap的属性:

复制代码
1      // 用于保持顺序的比较器,如果为空的话使用自然顺保持Key的顺序
2     private final Comparator<? super K> comparator;
3     // 根节点
4     private transient Entry<K,V> root = null;
5     // 树中的节点数量
6     private transient int size = 0;
7     // 多次在集合类中提到了,用于举了结构行的改变次数
8     private transient int modCount = 0;
复制代码

    注释中已经给出了属性的解释,下面看TreeMap的构造方法。

复制代码
 1 // 构造方法一,默认的构造方法,comparator为空,即采用自然顺序维持TreeMap中节点的顺序
 2 public TreeMap() {
 3     comparator = null;
 4 }
 5 // 构造方法二,提供指定的比较器
 6 public TreeMap(Comparator<? super K> comparator) {
 7     this.comparator = comparator;
 8 }
 9 // 构造方法三,采用自然序维持TreeMap中节点的顺序,同时将传入的Map中的内容添加到TreeMap中
10 public TreeMap(Map<? extends K, ? extends V> m) {
11     comparator = null;
12     putAll(m);
13 }
14 /** 
15 *构造方法四,接收SortedMap参数,根据SortedMap的比较器维持TreeMap中的节点顺序,* 同时通过buildFromSorted(int size, Iterator it, java.io.ObjectInputStream str, V defaultVal)方* 法将SortedMap中的内容添加到TreeMap中
16 */
17 public TreeMap(SortedMap<K, ? extends V> m) {
18     comparator = m.comparator();
19     try {
20         buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
21     } catch (java.io.IOException cannotHappen) {
22     } catch (ClassNotFoundException cannotHappen) {
23     }
24 }
复制代码

     TreeMap提供了四个构造方法,已经在注释中给出说明。构造方法中涉及到的方法在下文中会有介绍。

     下面从put/get方法开始,逐个分析TreeMap的方法。

     put(K key, V value)

复制代码
 1     public V put(K key, V value) {
 2         Entry<K,V> t = root;
 3         if (t == null) {
 4         //如果根节点为null,将传入的键值对构造成根节点(根节点没有父节点,所以传入的父节点为null)
 5             root = new Entry<K,V>(key, value, null);
 6             size = 1;
 7             modCount++;
 8             return null;
 9         }
10         // 记录比较结果
11         int cmp;
12         Entry<K,V> parent;
13         // 分割比较器和可比较接口的处理
14         Comparator<? super K> cpr = comparator;
15         // 有比较器的处理
16         if (cpr != null) {
17             // do while实现在root为根节点移动寻找传入键值对需要插入的位置
18             do {
19                 // 记录将要被掺入新的键值对将要节点(即新节点的父节点)
20                 parent = t;
21                 // 使用比较器比较父节点和插入键值对的key值的大小
22                 cmp = cpr.compare(key, t.key);
23                 // 插入的key较大
24                 if (cmp < 0)
25                     t = t.left;
26                 // 插入的key较小
27                 else 
TreeMap原理实现及常用方法 目录 一. TreeMap概述 二. 红黑树回顾 三. TreeMap构造 四. put方法 五. get 方法 六. remove方法 七. 遍历 八. 总结 前面我们分别讲了Map接口的两个实现类HashMap和LinkedHashMap,本章我们讲一下Map接口另一个重要的实现类TreeMap,TreeMap或许不如HashMap那么常用,但存在即合理,它也有自己的应用场景,TreeMap可以实现元素的自动排序。 一. TreeMap概述 TreeMap存储K-V键值对,通过. 阅读详情

相关推荐

【JAVA】TreeMap 详解

TreeMap 详解

weixin_37559642的博客 4023

Java中的常见五种map容器源码分析总结(HashMap、Hashtable、ConcurrentHashMap、LinkedHashMap、TreeMap)

  断断续续写了半个月,今天终于把TreeMap容器中的红黑树搞定了,现在来水一篇又快又短的Java Map容器总结博客 ????????。 注明:本篇博客不会涉及容器的源码什么的,主要是总结各个map容器的底层实现特点、主要运用场景。如果你需要详细了解更多关于Java中的map容器实现的细节,文末会提供我前面写的源码分析的博客链接,欢迎阅读。 Java中的常见五种map容器源码分析总结目录一、`Java`中...

hestyle的博客 1658

TreeMap源码分析解读

TreeMap

mbmispig的博客 4314

TreeMap详解:Java 有序 Map 原理与实现

在Java中,Map是一种常见的数据结构,它可以用来存储键值对。TreeMap是Java中的一个特殊的Map实现,它是基于红黑树实现的,具有排序和查找的功能。在本文中,我们将详细介绍TreeMap的使用和原理。本文主要介绍了Java中的TreeMap数据结构,包括其源代码解析、应用场景案例、优缺点分析、类代码方法介绍、测试用例和全文小结。通过对TreeMap的学习,读者可以了解到TreeMap的特点和使用方法,以及它与其他Map实现的不同之处。TreeMap是Java中的一个SortedMap。

喵手的博客 4461

Cadence AMS数模混合仿真:从零搭建高效验证环境的实战指南

本文是Cadence AMS数模混合仿真的实战指南,详细介绍了如何从零搭建高效的芯片验证环境。内容涵盖环境准备、Testbench创建、核心Config视图与ADE设置、仿真运行调试及性能加速技巧,旨在帮助工程师解决SoC设计中数字与模拟模块的集成验证难题,确保芯片设计一次成功。

weixin_29164091的博客 324

Linux虚拟机mysql安装教程(详细步骤)出现了一个错误:依赖检测失败

Linux虚拟机安装mysql的详细步骤(有报错预警哦)

m0_74953387的博客 5258

angular中访问本地json文件

先在assets文件夹下写一个json文件,这样在打完包之后也可以手动修改json文件内容 1、在需要访问本地json文件的ts文件里面引入 import{HttpClient}from'@angular/common/http'; 2、用ajax请求调用,我这里是用已经封装好的ajax请求调用 gethttp = ()=>{ var self = this self.ajax.getAjax("../../assets/server.json","g...

蜗牛~~ 1830

磁感应强度B、磁场强度H、矢量磁位A的study

学完电磁场很久了但是对电磁场中磁感应强度B⃗\vec{B}B、磁场强度HHH、矢量磁位A⃗\vec{A}A,这几个变量所表征的含义一直很模糊,所以就总结了一下

sinat_42386289的博客 1万+

让 ABAP 内表真正释放内存:从 CLEAR、FREE 到打破 Table Sharing 的实战技巧

ABAP内表内存管理的关键在于理解其运行时结构:DELETE操作仅逻辑删除行而不会释放内存,CLEAR或FREE才能真正回收内存。常见的误区包括误判空表状态和忽视内表共享机制。实际应用中,大表筛选后应采用VALUE表达式或逐行插入方式重建表体以释放内存。典型案例显示,正确处理内表内存可显著降低SAP Gateway和批处理程序的内存消耗,提升系统稳定性。开发时需结合调试工具观察内存状态,避免因共享机制导致无效回收。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 325

家人们,谁懂啊,dify又报错了:[models] Bad Request Error, 500 Server Error:Internal Server Error for url: http://

本来今天下班,坐在地铁上,一身劳累。一起上班的小兄弟儿,突然甩来一张截图:老大!dify又报错了。没办法,一到家就打开电脑,开始排查。

xiezhipu的博客 883

ComfyUI整合包V8中文版最新版介绍

和普通AI绘图网页不同,它把图像生成的每一个步骤拆分成一个个"节点",用连线把它们串起来,形成工作流。里面包含ComfyUI内核、Python运行环境、常用插件、部分预置模型,还有一个叫"绘世启动器"的图形界面管理工具。网上的对比数据显示,WebUI最低需要4G显存,ComfyUI最低3G显存就能运行。可以在里面管理插件、切换模型路径、设置显存模式、查看日志报错,还有"疑难解答"功能,遇到报错可以先扫描一下看是不是已知问题。原版ComfyUI的界面是英文的,右键菜单、节点名称全是英文。

欢迎来到鸾姝淡月博客,专为程序员和编程爱好者打造的技术博客。我们分享编程语言趋势、开发工具、编程哲学、职业发展等,助你掌握新技术,优化技能,激发编程热情。 5228

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

上一篇: java源码分析之HashSet及LinkedHashSet
下一篇: java源码分析之TreeMap深入篇
快乐的燕子会飞
博客等级 码龄14年 417粉丝 68原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值