HashMap和TreeMap区别详解以及底层实现

HashMap和TreeMap区别详解以及底层实现前言首先介绍一下什么是 Map 在数组中我们是通过数组下标来对其内容索引的 而在 Map 中我们通过对象来对对象进行索引 用来索引的对象叫做 key 其对应的对象叫做 value 这就是我们平时说的键值对 HashMap 通过 hashcode 对其内容进行快速查找 而 TreeMap 中所有的元素都保持着某种固定的顺序 如果你需要得到一个有序的结果你就应该使用 TreeMap HashMap 中元素的排列顺序是不固定的

前言

首先介绍一下什么是Map.在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.这就是我们平时说的键值对。

HashMap通过hashcode对其内容进行快速查找,而 TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。

HashMap 代码分析

HashMap 是基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。


官方文档如下:
此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get 和 put)提供稳定的性能。迭代 collection 视图所需的时间与 HashMap 实例的“容量”(桶的数量)及其大小(键-值映射关系数)成比例。所以,如果迭代性能很重要,则不要将初始容量设置得太高(或将加载因子设置得太低)。

HashMap 的实例有两个参数影响其性能:初始容量 和加载因子。容量 是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。

通常,默认加载因子 (.75) 在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。

如果很多映射关系要存储在 HashMap 实例中,则相对于按需执行自动的 rehash 操作以增大表的容量来说,使用足够大的初始容量创建它将使得映射关系能更有效地存储。

注意,此实现不是同步的。如果多个线程同时访问一个哈希映射,而其中至少一个线程从结构上修改了该映射,则它必须 保持外部同步。(结构上的修改是指添加或删除一个或多个映射关系的任何操作;仅改变与实例已经包含的键关联的值不是结构上的修改。)这一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedMap 方法来“包装”该映射。最好在创建时完成这一操作,以防止对映射进行意外的非同步访问,如下所示:


Map.put()的时候,需要将key值映射为相应的hash值,key的值是以char数组的形式存放的,value对应的值也是有char数组存放的

这里写图片描述

这里写图片描述

在进行存放的时候,首先检查table是否为空,如果为空使用inflateTable方法进行初始化操作。

这里写图片描述

然后就是调用hash方法,找到具体的key所对应的hash,然后再到entry中去找value

TreeMap代码分析

这里写图片描述

看到上边,可知TreeMap并不是基于hash实现的,据说是红黑树,红黑树这块几乎空白,不敢多说:


官方文档:
基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。

此实现为 containsKey、get、put 和 remove 操作提供受保证的 log(n) 时间开销。这些算法是 Cormen、Leiserson 和 Rivest 的 Introduction to Algorithms 中的算法的改编。

注意,如果要正确实现 Map 接口,则有序映射所保持的顺序(无论是否明确提供了比较器)都必须与 equals 一致。(关于与 equals 一致 的精确定义,请参阅 Comparable 或 Comparator)。这是因为 Map 接口是按照 equals 操作定义的,但有序映射使用它的 compareTo(或 compare)方法对所有键进行比较,因此从有序映射的观点来看,此方法认为相等的两个键就是相等的。即使排序与 equals 不一致,有序映射的行为仍然是 定义良好的,只不过没有遵守 Map 接口的常规协定。

注意,此实现不是同步的。如果多个线程同时访问一个映射,并且其中至少一个线程从结构上修改了该映射,则其必须 外部同步。(结构上的修改是指添加或删除一个或多个映射关系的操作;仅改变与现有键关联的值不是结构上的修改。)这一般是通过对自然封装该映射的对象执行同步操作来完成的。如果不存在这样的对象,则应该使用 Collections.synchronizedSortedMap 方法来“包装”该映射。最好在创建时完成这一操作,以防止对映射进行意外的不同步访问,如下所示:


HashMap和TreeMap比较

 在HashMap中通过get()来获取value,通过put()来插入value,ContainsKey()则用来检验对象是否已经存在。可以看出,和ArrayList的操作相比,HashMap除了通过key索引其内容之外,别的方面差异并不大。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/223486.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午2:05
下一篇 2026年3月17日 下午2:06


相关推荐

  • linux查看操作系统版本信息

    linux查看操作系统版本信息一 linux 下如何查看已安装的 centos 版本信息 1 Linux 查看当前操作系统版本信息 cat proc versionLinux 6 32 696 el6 x86 64 gccversion4 4 RedHat4 4 7 18 GCC 1SMPTueMar21 29 05UTC20172 Linux 查看版本当前操作系统内核信息 uname

    2026年3月17日
    2
  • .net pdf转word_pdf to word

    .net pdf转word_pdf to wordAsposewordpdf相互转换工具类文件的详细路径:pdfToDoc(StringpdfPath,StringdocPath)输入流:pdfToDoc(InputStreampdfPathInputStream,StringdocPath)//Anhighlightedblockpackagecom.example.wordpdf.utils;importcom.aspose.pdf.License;importcom.aspose.pdf.SaveF

    2025年7月23日
    6
  • ocker nginx 配置反向代理和负载均衡[通俗易懂]

    ocker nginx 配置反向代理和负载均衡

    2022年4月2日
    43
  • 如何在Pycharm上安装PyQt5[通俗易懂]

    如何在Pycharm上安装PyQt5[通俗易懂]这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML图表FLowchart流程图导出与导入导出导入欢迎使用Markdown编辑器你好!这是你第一次使用Markdown编辑器所展示的欢迎页。如果你想学习如何使用Mar

    2022年8月25日
    9
  • 指针函数和函数指针「建议收藏」

    指针函数和函数指针「建议收藏」概述指针函数和函数指针是C语言里两个比较绕的概念。但是不仅面试题爱考,实际应用中也比较广泛。很多人因为搞不清这两个概念,干脆就避而远之,我刚接触C语言的时候对这两个概念也比较模糊,特别是当指针函数、函数指针、函数指针变量、函数指针数组放在一块的时候,能把强迫症的人活活逼疯。其实如果理解了这些概念的本质,是不需要死记硬背的,理解起来也比较容易。指针函数指针函数:顾名思义,它的本质是一个函数…

    2022年6月22日
    33
  • 使用百度地图——入门

    使用百度地图——入门

    2022年1月17日
    46

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号