从源码分析HashMap与HashTable的详细区别

总结:

  1. 继承的父类不同:HashTable继承自Dictionary类,而HashMap继承自AbstractMap类。但二者都实现了Map接口

  2. 线程安全性:HashMap是非线程安全的,而HashTable是线程安全的,通过源码分析我们知道HashTable的每个方法都是实现了synchronized

  3. key和value是否允许null值:HashMap可以存储key=null的键值对,HashTable不能存储key=null的键值对

  4. hash值不同:HashTable直接使用对象的hashCode。而HashMap重新计算hash值

  5. 默认初始容量及如何扩容不同:HashMap的默认初始容量是16,HashTable默认初始容量是11;HashMap和HashTable的加载因子都是0.75;HashMap扩容:2N,而HashTable扩容:2N+1.

源码分析
在这里插入图片描述

1. 继承的父类不同

HashMap

在这里插入图片描述

HashTable在这里插入图片描述

2. 线程安全性

HashMap的PUT方法在这里插入图片描述

HashTable的PUT方法在这里插入图片描述

如此我们可以看出,HashMap是线程不安全的,因此他们之间的区别有线程安全性不同。

3. key和value是否允许null值

HashMap的containsValue方法源码

在这里插入图片描述

HashTable的containsValue方法源码

在这里插入图片描述

通过上面的ContainsKey方法和ContainsValue的源码我们可以很明显的看出:

  • Hashtable中,key和value都不允许出现null值。但是如果在Hashtable中有类似put(null,null)的操作,编译同样可以通过,因为key和value都是Object类型,但运行时会抛出NullPointerException异常,这是JDK的规范规定的;
  • HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,可能是 HashMap中没有该键,也可能使该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。

4. hash值不同

哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值
hashCode是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值

HashMap

put方法

在这里插入图片描述

hash方法在这里插入图片描述

HashTable

在这里插入图片描述

Hashtable计算hash值,直接用key的hashCode(),而HashMap重新计算了key的hash值,Hashtable在求hash值对应的位置索引时,用取模运算,而HashMap在求位置索引时,则用与运算,且这里一般先用hash&0x7FFFFFFF后,再对length取模,&0x7FFFFFFF的目的是为了将负的hash值转化为正值,因为hash值有可能为负数,而&0x7FFFFFFF后,只有符号外改变,而后面的位都不变。

5. 默认初始容量及如何扩容不同

HashTable

在这里插入图片描述
在这里插入图片描述

HashMap在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44723496/article/details/112440968