文章目录

  • 简介
  • HashMap和TreeMap本质区别
  • 排序区别
  • Null值的区别
  • 性能区别
  • 共同点

深入理解HashMap和TreeMap的区别

简介

HashMap和TreeMap是Map家族中非常常用的两个类,两个类在使用上和本质上有什么区别呢?本文将从这两个方面进行深入的探讨,希望能揭露其本质。

HashMap和TreeMap本质区别

先看HashMap的定义:

public class HashMap<K,V> extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable

再看TreeMap的定义:

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

从类的定义来看,HashMap和TreeMap都继承自AbstractMap,不同的是HashMap实现的是Map接口,而TreeMap实现的是NavigableMap接口。NavigableMap是SortedMap的一种,实现了对Map中key的排序。

这样两者的第一个区别就出来了,TreeMap是排序的而HashMap不是。

再看看HashMap和TreeMap的构造函数的区别。

public HashMap(int initialCapacity, float loadFactor)

HashMap除了默认的无参构造函数之外,还可以接受两个参数initialCapacity和loadFactor。

HashMap的底层结构是Node的数组:

transient Node<K,V>[] table

initialCapacity就是这个table的初始容量。如果大家不传initialCapacity,HashMap提供了一个默认的值:

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

当HashMap中存储的数据过多的时候,table数组就会被装满,这时候就需要扩容,HashMap的扩容是以2的倍数来进行的。而loadFactor就指定了什么时候需要进行扩容操作。默认的loadFactor是0.75。

static final float DEFAULT_LOAD_FACTOR = 0.75f;

再来看几个非常有趣的变量:

static final int TREEIFY_THRESHOLD = 8;
static final int UNTREEIFY_THRESHOLD = 6;
static final int MIN_TREEIFY_CAPACITY = 64;

上面的三个变量有什么用呢?在java 8之前,HashMap解决hashcode冲突的方法是采用链表的形式,为了提升效率,java 8将其转成了TreeNode。什么时候会发送这个转换呢?

这时候就要看这两个变量TREEIFY_THRESHOLD和UNTREEIFY_THRESHOLD。

有的同学可能发现了,TREEIFY_THRESHOLD为什么比UNTREEIFY_THRESHOLD大2呢?其实这个问题我也不知道,但是你看源代码的话,用到UNTREEIFY_THRESHOLD时候,都用的是<=,而用到TREEIFY_THRESHOLD的时候,都用的是>= TREEIFY_THRESHOLD - 1,所以这两个变量在本质上是一样的。

MIN_TREEIFY_CAPACITY表示的是如果table转换TreeNode的最小容量,只有capacity >= MIN_TREEIFY_CAPACITY的时候才允许TreeNode的转换。

TreeMap和HashMap不同的是,TreeMap的底层是一个Entry:

private transient Entry<K,V> root

他的实现是一个红黑树,方便用来遍历和搜索。

TreeMap的构造函数可以传入一个Comparator,实现自定义的比较方法。

public TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;}

如果不提供自定义的比较方法,则使用的是key的natural order。

排序区别

我们讲完两者的本质之后,现在举例说明,先看下两者对排序的区别:

    @Testpublic void withOrder(){Map<String, String> books = new HashMap<>();books.put("bob", "books");books.put("c", "concurrent");books.put("a", "a lock");log.info("{}",books);}
    @Testpublic void withOrder(){Map<String, String> books = new TreeMap<>();books.put("bob", "books");books.put("c", "concurrent");books.put("a", "a lock");log.info("{}",books);}

同样的代码,一个使用了HashMap,一个使用了TreeMap,我们会发现TreeMap输出的结果是排好序的,而HashMap的输出结果是不定的。

Null值的区别

HashMap可以允许一个null key和多个null value。而TreeMap不允许null key,但是可以允许多个null value。

    @Testpublic void withNull() {Map<String, String> hashmap = new HashMap<>();hashmap.put(null, null);log.info("{}",hashmap);}
    @Testpublic void withNull() {Map<String, String> hashmap = new TreeMap<>();hashmap.put(null, null);log.info("{}",hashmap);}

HashMap会报出: NullPointerException。

性能区别

HashMap的底层是Array,所以HashMap在添加,查找,删除等方法上面速度会非常快。而TreeMap的底层是一个Tree结构,所以速度会比较慢。

另外HashMap因为要保存一个Array,所以会造成空间的浪费,而TreeMap只保存要保持的节点,所以占用的空间比较小。

HashMap如果出现hash冲突的话,效率会变差,不过在java 8进行TreeNode转换之后,效率有很大的提升。

TreeMap在添加和删除节点的时候会进行重排序,会对性能有所影响。

共同点

两者都不允许duplicate key,两者都不是线程安全的。

本文的例子https://github.com/ddean2009/learn-java-collections

更多精彩内容且看:

  • 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
  • Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
  • Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
  • java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程

欢迎关注我的公众号:程序那些事,更多精彩等着您!
更多内容请访问 www.flydean.com

深入理解HashMap和TreeMap的区别相关推荐

  1. 深入理解HashMap和LinkedHashMap的区别

    文章目录 简介 LinkedHashMap详解 插入 访问 removeEldestEntry 总结 深入理解HashMap和LinkedHashMap的区别 简介 我们知道HashMap的变量顺序是 ...

  2. HashMap 与 TreeMap的区别

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

  3. Java中HashMap和TreeMap的区别深入理解,java开发面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...

  4. Java中HashMap和TreeMap的区别深入理解

    2019独角兽企业重金招聘Python工程师标准>>> 首先介绍一下什么是Map.在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象 ...

  5. Java比较同一map是否相同_Java 中HashTable、HashMap、TreeMap三者区别,以及自定义对象是否相同比较,自定义排序等...

    /* Map集合:该集合存储键值对.一对一对往里存.而且要保证键的唯一性. Map |--Hashtable:底层是哈希表数据结构,不可以存入null键null值.该集合是线程同步的.效率低.基本已废 ...

  6. java基础—Hashtable,HashMap,TreeMap的区别

    Hashtable : 此类实现一个哈希表,该哈希表将键映射到相应的值,任何非null  对象都可以作键值,是线程不同步的 HashMap : 基于哈希表的Map接口的实现,此实现提供所有可选的映射操 ...

  7. Java中HashMap和TreeMap的区别

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

  8. 深度理解 HashMap 和 Hashtable 的区别

    这只是基础: HashMap 和 Hashtable 都实现了 Map 接口,因此很多特性非常相似.但是,他们有以下不同点: HashMap 允许键和值是 null,而 Hashtable 不允许键或 ...

  9. java中HashMap,LinkedHashMap,TreeMap,HashTable的区别

    java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap Map主要用于存储健值对,根 ...

最新文章

  1. 《Ansible权威指南 》一 第一篇 Part 1 基础入门篇
  2. android 百度悬浮搜索框,百度的搜索框效果如何实现的???
  3. MaxScale Binlog Server
  4. 【美文欣赏】人人都有难念的经
  5. nvme通用驱动_对领域驱动设计的理解与实践
  6. 【论文写作】SSM超市管理系统如何写可行性分析
  7. Eclipse中集成SVN
  8. qt通过http连接mysql_Azure Database for MySQL 连接安全-(3) Private Endpoint
  9. ThinkPHP基础
  10. 用手机otg方式给U盘制作一个Win10PE启动U盘,手机加U盘协助电脑重装系统
  11. SpringBoot工作原理
  12. Win32反汇编(七)浮点指令(FLD / FILD / FSTP)与位移指令的逆向分析
  13. Unity 编辑器开发实战【Scene View】- UI Selector
  14. IEEE Fellow 2019 名单出炉,40 位国内高校学者入选
  15. SpringBoot框架的环境搭建与使用
  16. 走近棒球运动·芝加哥小熊队·MLB棒球创造营
  17. 【HarmonyOS】鸿蒙3.0使用WebView进行链接跳转,告警“hwbr_engine_AwContentsClient: Denied starting an intent without a
  18. java反射的作用于原理、初学者
  19. cf服务器无响应,穿越火线优化玩家分辨率,告别白屏未响应!
  20. 【Linux 中国】最适合程序员的 10 款 Linux 发行版

热门文章

  1. 排序算法-01冒泡排序(Python实现)
  2. 【数据结构】图的应用(普利姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、拓扑排序)
  3. LiveVideoStackCon 专题评审团招募进行中
  4. 【视频编解码的新挑战与新机会】
  5. 探讨TensorRT加速AI模型的简易方案 — 以图像超分为例
  6. LiveVideoStack线上分享第四季(五):基于Airflow的视频编码平台
  7. HEVC支持苹果HLS的几个关键问题
  8. C/C++学习之路: C++对C的扩展
  9. Hadoop之HDFS面试知识复习
  10. 基于Kubeflow建立的星辰算力训练平台背后的技术架构