HashMap 和 Hashtable 的同和不同

本文详细解释了如何正确使用hashcode和equals方法来判断对象的相等性,并探讨了HashMap和Hashtable的区别及其内部实现机制。此外,还介绍了HashMap的一些关键特性,如初始容量和负载因子对性能的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

综述

可以直接根据 hashcode 值判断两个对象是否相等吗?肯定是不可以的,因为不同的对象可能会生成相同的 hashcode 值。虽然不能根据 hashcode 值判断两个对象是否相等,但是可以直接根据 hashcode 值判断两个对象不等,如果两个对象的 hashcode 值不等,则必定是两个不同的对象。如果要判断两个对象是否真正相等,必须通过 equals 方法。

也就是说对于两个对象,如果调用 equals 方法得到的结果为 true,则两个对象的 hashcode 值必定相等;如果 equals 方法得到的结果为 false,则两个对象的 hashcode 值不一定不同;如果两个对象的 hashcode 值不等,则 equals 方法得到的结果必定为 false;如果两个对象的 hashcode 值相等,则 equals 方法得到的结果未知。

HashMap 和 Hashtable 不保证 map 的顺序,也不保证顺序不会随着时间不变。

HashMap 实例有两个参数影响性能:初始 capacity 和 load factor。capacity 是 hashtable 中桶的数量,初始 capacity 就是 hashtable 创建时的 capacity。load factor 影响 hashtable 多满时允许自动增加 capacity。当 hashtable 中 entry 的数量超过 load factor 和当前 capacity 的乘积,hashtable 会重新哈希(意味着,内部数据结构重建)因此 hashtable 大约拥有桶数量的两倍。

作为通用规则,默认 load factor(0.75)在时间和空间消耗上提供了好的权衡。值越大,空间开销越小,但是遍历成本增加(表现在大多数操作,包括 get 和 put)。当设置初始 capacity 时,为了最小化重新 hash 的操作次数,应该考虑 map的 entry 数量和 load factor。如果初始容量大于最大 entry 数量除以 load factor ,重新 hash 操作将不会发生。然而,设置初始 capacity 太大会浪费空间。

如果许多 mapping 存储在 HashMap 实例中,创建时使用足够大的 capacity 将允许 mapping 存储得更有效率,因为不会随着 table 的数量增大重新 hash。注意使用许多相同 hashCode() 的 key 肯定会降低任意 hashtable 的性能。

相同点

成员变量
DEFAULT_LOAD_FACTOR0.75
TREEIFY_THRESHOLD8
UNTREEIFY_THRESHOLD6
MIN_TREEIFY_CAPACITY否则resize()64
sizemapping 数量
threholdcapacity*load factor

不同点

HashMapHashtable
线程安全不安全安全
允许null的键和值允许不允许
实现和继承实现Map实现Map,继承Dictionary
遍历方式IteratorIterator和Enumeration
计算哈希值(key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16)(key.hashCode() & 0x7FFFFFFF)
计算数组下标(length - 1) & hashhash % length
DEFAULT_INITIAL_CAPACITY1611
容量增加方式old*2长度始终为2的幂old*2+1
构造函数threshold=tableSizeFor(initialCapacity)threhold=initialCapacity*load factor
resize从0-cap链表顺序不变从cap-0链表顺序相反

注意点:

计算数组下标:当length总是2的n次方时,h & (length - 1)运算等价于对 length 取模,也就是 h % length,但是&比%具有更高的效率。

容量增加方式:当数组长度为 2 的 n 次幂的时候,不同的 key 算得的 index 相同的几率较小,那么数据在数组上分布就比较均匀,也就是说碰撞的几率小。相对的,查询的时候就不用遍历某个位置上的链表,这样查询效率也就较高了。导致 resize() 不同 HashMap 直接使用之前的数组下表,而 Hashtable 需要重新计算。

转载于:https://www.cnblogs.com/studyhs/p/9088229.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值