当前位置:首页 » 《随便一记》 » 正文

HashMap和Hashtable的区别

9 人参与  2023年04月01日 09:22  分类 : 《随便一记》  评论

点击全文阅读


相同点:

HashMap和Hashtable都是java.util包下的类HashMap和Hashtable都实现了Map接口,存储方式都是key-value形式HashMap和Hashtable同时也都实现了Serializable和Cloneable接口HashMap和Hashtable的负载因子都是0.75

负载因子(loadFactor):
当我们第一次创建 HashMap 的时候,就会指定其容量(如果未明确指定,默认是 16),随着我们不断的向 HashMap 中 put 元素的时候,就有可能会超过其容量,那么就需要有一个扩容机制。

所谓扩容,就是扩大 HashMap 的容量,在向 HashMap 中添加元素过程中,如果 元素个数(size)超过临界值(threshold) 的时候,就会进行自动扩容(resize),并且,在扩容之后,还需要对 HashMap 中原有元素进行 rehash,即将原来桶中的元素重新分配到新的桶中。

在 HashMap 中,临界值(threshold) = 负载因子(loadFactor) * 容量(capacity)。

loadFactor 是装载因子(负载因子),表示 HashMap 满的程度,默认值为 0.75f,也就是说默认情况下,当 HashMap 中元素个数达到了容量的 3/4 的时候就会进行自动扩容。

HashMap与Hashtable的部分方法相同,如put,remove等方法

不同点:

1. HashMap是非线程安全的,Hashtable是线程安全的

书写如下代码分别查看HashMap和Hashtable的put方法。

HashMap:当我们进入put方法查看源码时可以发现put方法返回的方法只有个finla修饰,没有任何关于线程的存在

在这里插入图片描述

Hashtable:当我们点击进入之后,就能马上看到一个synchronized关键字,表示这个方法在调用的时候不能被其他的线程对象访问。
在这里插入图片描述
2. HashMap允许null作为键或值,Hashtable不允许,运行时会报NullPointerException
从上面Hashtable的put方法中我们也可以明显的看出,当我们的value值为null时,会抛出一个异常我们输出刚刚书写的代码时,也可以看出。当我们分别给HashMap和Hashtable传入空值时,分别查看它们的size时,HashMap会得到一个1,而Hashtable则会抛出一个NullPointerException
在这里插入图片描述
3. HashMap添加元素使用的是自定义hash算法,Hashtable使用的是key的hashCode
HashMap使用的是自定义的算法,当我们进入put方法查看时,看见put方法中return了一个叫putVal的方法,刚方法前面把这个key传进去又调用了一个叫hash的方法,这个是它自己的方法,点进去之后会发现,他又将这个key获取了一个hashcode,然后把它右移了16位,跟当前的hashcode做了一个异或。进入put方法在这里插入图片描述
- 进入hash方法
在这里插入图片描述而Hashtable进入put方法后可以看见,它只是调用了当前key自己的hashcode方法所以两个虽然都是hash的算法,但是算法的本质上是不太一样的
4. HsahMap在数组+链表的结构中引入了红黑树,Hashtable没有

hash结构它的底层数据结构存储应该是一个数组加列表的形式,所以HashMap和Hashtable它的底层存储机制都是数组加列表的结构,但是在jdk 1.8版本之后HashMap增加了一个新的结构叫做红黑树。
源码中的具体体现:
map.put方法中有两个非常明显的节点,一个叫做Node,一个叫做TreeNode,而这个Node存的就是普通的值(一个键,一个值,一个hash),而TreeNode存的则是当前节点的父元素、左元素、右元素,还有一个boolean类型的red(记录是否为红节点)。
这个结构Hashtable没有,而且这个结构如果长度链表长度超过8个的话,他就会自动进行红黑树的变化,然后在链表长度小于6个的时候就会变回去。

进入putVal方法后可以看见Node和Tree Node两个节点
在这里插入图片描述当我们点击Node进入之后,会发现他存的是这样一个结构;hash然后key、value,加上下一个节点
而TreeNode他存储的就不是了。而是当前节点的父元素、左元素、右元素,还有一个boolean类型的red(记录是否为红节点)。
在这里插入图片描述
5. HashMap初始容量为16,Hashtable初始容量为11
HashMap:默认初始容量为16
在这里插入图片描述Hashtable:默认初始容量是11个,Hashtable有一个构造方法,在构建Hashtable对象的时候传了一个11的默认值进去
在这里插入图片描述
6. HsahMap扩容是当前容量翻倍,Hashtable是当前容量翻倍+1
HashMap:首先进入putVal方法,可以看到它有一个方法叫做resize,就是重新定义长度
在这里插入图片描述
而这里面机制就是old容量往左移一位,刚好就是乘2
在这里插入图片描述Hashtable也是同样有一个方法这个方法叫做addEntry,这个方法中有一个叫rehash方法,这个方法就是重新算长度的方法,
在这里插入图片描述
进入之后可以看见old往左移一位,但是后面又加了一个1

在这里插入图片描述

7. HsahMap只支持Iterator遍历,Hashtable支持Iterator和Enumeration

遍历的机制HashMap有一个叫keyset还有一个叫Entryset的两个方法,得到的结果都是Iterator(迭代器)。

而Hashtable有一个叫elements的方法,他的结果是Enumeration,同时Hashtable也能得到key和Entry,所以Hashtable的遍历方式多了一个机制。

8. HsahMap与Hashtable的部分方法不同,比如Hashtable有contains方法。

Hashtable中有contains方法,HsahMap中就没有。HsahMap只有containsKey和containsValue但是没有contains。


点击全文阅读


本文链接:http://zhangshiyu.com/post/57719.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1