深入理解HashMap和TreeMap的区别
文章目录
- 简介
- 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的区别相关推荐
- 深入理解HashMap和LinkedHashMap的区别
文章目录 简介 LinkedHashMap详解 插入 访问 removeEldestEntry 总结 深入理解HashMap和LinkedHashMap的区别 简介 我们知道HashMap的变量顺序是 ...
- HashMap 与 TreeMap的区别
HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固 ...
- Java中HashMap和TreeMap的区别深入理解,java开发面试笔试题
我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...
- Java中HashMap和TreeMap的区别深入理解
2019独角兽企业重金招聘Python工程师标准>>> 首先介绍一下什么是Map.在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象 ...
- Java比较同一map是否相同_Java 中HashTable、HashMap、TreeMap三者区别,以及自定义对象是否相同比较,自定义排序等...
/* Map集合:该集合存储键值对.一对一对往里存.而且要保证键的唯一性. Map |--Hashtable:底层是哈希表数据结构,不可以存入null键null值.该集合是线程同步的.效率低.基本已废 ...
- java基础—Hashtable,HashMap,TreeMap的区别
Hashtable : 此类实现一个哈希表,该哈希表将键映射到相应的值,任何非null 对象都可以作键值,是线程不同步的 HashMap : 基于哈希表的Map接口的实现,此实现提供所有可选的映射操 ...
- Java中HashMap和TreeMap的区别
什么是Map集合在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.这就是我们平时说的键值对. HashMap ...
- 深度理解 HashMap 和 Hashtable 的区别
这只是基础: HashMap 和 Hashtable 都实现了 Map 接口,因此很多特性非常相似.但是,他们有以下不同点: HashMap 允许键和值是 null,而 Hashtable 不允许键或 ...
- java中HashMap,LinkedHashMap,TreeMap,HashTable的区别
java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap Map主要用于存储健值对,根 ...
最新文章
- 《Ansible权威指南 》一 第一篇 Part 1 基础入门篇
- android 百度悬浮搜索框,百度的搜索框效果如何实现的???
- MaxScale Binlog Server
- 【美文欣赏】人人都有难念的经
- nvme通用驱动_对领域驱动设计的理解与实践
- 【论文写作】SSM超市管理系统如何写可行性分析
- Eclipse中集成SVN
- qt通过http连接mysql_Azure Database for MySQL 连接安全-(3) Private Endpoint
- ThinkPHP基础
- 用手机otg方式给U盘制作一个Win10PE启动U盘,手机加U盘协助电脑重装系统
- SpringBoot工作原理
- Win32反汇编(七)浮点指令(FLD / FILD / FSTP)与位移指令的逆向分析
- Unity 编辑器开发实战【Scene View】- UI Selector
- IEEE Fellow 2019 名单出炉,40 位国内高校学者入选
- SpringBoot框架的环境搭建与使用
- 走近棒球运动·芝加哥小熊队·MLB棒球创造营
- 【HarmonyOS】鸿蒙3.0使用WebView进行链接跳转,告警“hwbr_engine_AwContentsClient: Denied starting an intent without a
- java反射的作用于原理、初学者
- cf服务器无响应,穿越火线优化玩家分辨率,告别白屏未响应!
- 【Linux 中国】最适合程序员的 10 款 Linux 发行版
热门文章
- 排序算法-01冒泡排序(Python实现)
- 【数据结构】图的应用(普利姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、拓扑排序)
- LiveVideoStackCon 专题评审团招募进行中
- 【视频编解码的新挑战与新机会】
- 探讨TensorRT加速AI模型的简易方案 — 以图像超分为例
- LiveVideoStack线上分享第四季(五):基于Airflow的视频编码平台
- HEVC支持苹果HLS的几个关键问题
- C/C++学习之路: C++对C的扩展
- Hadoop之HDFS面试知识复习
- 基于Kubeflow建立的星辰算力训练平台背后的技术架构