HashMap和Hashtable的区别

说道这个问题,可能我们都能总结一大堆,这个我们放在后面,先说说本质。

我们都知道HashMap的效率高线程不安全,多线程高并发的时候需要自己写同步锁,Hashtable线程安全,效率低。本质是啥?

算法不同

也就是计算hash值得方法不一样,原理都是通过通过元素的key计算hash值,然后再通过hash值计算最终位置。

Hashtable是直接使用对象的hashcode。hashcode是根据对象的地址或字符串或数字计算出来的int类型数值。再通过除留余数的方法获得位置

int hash=key.hashCode();
int index=(hash&0x7FFFFFF)%tab.length;

从源码可以看出,hashtable在计算元素的位置时需要进行一次除法,除法运算本来就比较耗时。

HashMap将哈希表的大小固定到了2的幂(这里两者区别后续会讲),这样就可以直接通过位运算取模,就不用耗时的除法。

HashMap的效率虽然提高了,但是hash冲突却也增加了。因为它得出的hash值的低位相同的概率比较高,而计算位运算

为了解决这个问题,HashMap重新根据hashcode计算hash值后,又对hash值做了一些运算来打散数据。使得取得的位置更加分散,从而减少了hash冲突。当然了,为了高效,HashMap只做了一些简单的位处理。从而不至于把使用2 的幂次方带来的效率提升给抵消掉。

初始容量大小和每次扩充容量大小的不同


Hashtable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。

创建时,如果给定了容量初始值,那么Hashtable会直接使用你给定的大小,而HashMap会将其扩充为2的幂次方大小。也就是说Hashtable会尽量使用素数、奇数。而HashMap则总是使用2的幂作为哈希表的大小。

之所以会有这样的不同,是因为Hashtable和HashMap设计时的侧重点不同。Hashtable的侧重点是哈希的结果更加均匀,使得哈希冲突减少。当哈希表的大小为素数时,简单的取模哈希的结果会更加均匀。而HashMap则更加关注hash的计算效率问题。在取模计算时,如果模数是2的幂,那么我们可以直接使用位运算来得到结果,效率要大大高于做除法。HashMap为了加快hash的速度,将哈希表的大小固定为了2的幂。当然这引入了哈希分布不均匀的问题,所以HashMap为解决这问题,又对hash算法做了一些改动。这从而导致了Hashtable和HashMap的计算hash值的方法不同


其他

HashtableHashMap
java产生就开始,现在不咋用jdk1.2开始,主流
每个方法都有Synchronize,线程安全,算法中有除法,效率低非线程安全,多线程并发需要自己加同步锁,也可以使用ConcurrentHashMap(线程安全,分段锁,效率高)。效率高
父类:Dictionary父类:AbsttactMap
实现接口:map、Cloneable(可复制)、Serializable(可序列化)
key和value都不能为null。空指针。key可以有一个null,value可以有一个或多个null。所以当get()方法返回null时,即可能是没有key值也有可能是key对应的value为null,需要用containskey()判断。
遍历方式:Iterator、Enumeration

遍历方式:Iterator(fail-fast)当有其他线程改变了HashMap的接口(增、删、改)会抛ConcurrentModificationException。Iterator的remove不会。

对外多提供两个接口:

elments() 继承Dictionary 返回value的枚举。

contains() 判断是否包含传入的value。

containsValue()作用=contains()

public boolean containsValue(Object value){

return contains(value);

}

初始容量:11,每次扩容变为原来的2n+1      16     2倍
给定初始值:n2的n次方
计算hash的方法:除法位运算

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值