文章目录
1、hashCode方法介绍
hashCode方法是Object类中的一个方法,用于返回对象的哈希码(不是返回内存地址,是一种随机算法生成的随机数,jvm启动时可以通过参数来改变对象hashcode生成规则)。哈希码是一个整数值,用于快速查找对象在哈希表中的位置。这个值在对象的生命周期内是固定的,只有当对象发生变化时,hashCode值才会改变。
2、hashCode的使用场景
- 哈希表数据结构:在使用基于哈希表的集合类(如HashMap、HashSet、Hashtable)时,哈希码被用于确定对象在集合内部数据结构中的存储位置。hashCode()方法的返回值用作哈希表的索引,以快速访问和检索对象。
- 键值对存储:在使用基于哈希表的映射类(如HashMap、Hashtable)时,哈希码被用于确定键的存储位置。hashCode()方法用于计算键的哈希码,然后根据哈希码将键值对存储在合适的位置。
- 自定义数据结构中的哈希算法:当你在自定义数据结构中使用哈希算法时,hashCode()方法用于计算对象的哈希码,以便进行快速的存储、检索和比较。
- 并发集合的分桶策略:在并发集合框架中,如ConcurrentHashMap,hashCode()方法被用于实现分桶策略,将不同的对象映射到不同的桶中,从而提高并发性能。
总结来说,hashCode()方法主要在基于哈希表的数据结构和算法中使用,用于确定对象在集合中的存储位置、键值对的存储位置以及自定义数据结构中的哈希算法。它对于提高存储、检索和比较的效率非常重要。
以HashSet为例
- HashSet首先会调用对象的hashCode()方法获取哈希码,并通过哈希码确定对象在集合中的存储位置。哈希码决定了对象在内部数据结构中的桶(bucket)索引。
- 如果该位置没有其他对象,HashSet将直接将对象存储在该位置,没有碰撞。
- 如果该位置已经保存了一个或多个对象(发生碰撞),HashSet会遍历链表中的每个对象,并使用equals()方法比较新对象和链表中的每个对象。
- 如果新对象与链表中的某个对象相等(根据equals()方法的定义),则认为对象重复,不会将新对象添加到HashSet中,以保持集合的唯一性。
- 如果新对象与链表中的所有对象都不相等,HashSet会将新对象添加到链表的末尾,形成链式结构。
总结起来,HashSet使用哈希码确定对象在集合中的存储位置,并使用equals()方法处理可能的哈希碰撞。如果发生碰撞,不相等的对象将被放在同一个位置的链表中。这样做是为了快速确定对象是否已经存在于集合中,并保持集合中元素的唯一性
3、eqauls方法和hashCode方法关系
1、如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。
2、如果两个对象不equals,他们的hashcode有可能相等。
3、如果两个对象hashcode相等,他们不一定equals。
4、如果两个对象hashcode不相等,他们一定不equals。
4、为什么覆盖equals时总要覆盖hashCode
原因:
- 一致性:
- equals()方法用于判断两个对象是否相等。
- 根据Java规范,如果两个对象通过equals()方法判断相等,它们的hashCode()方法必须返回相同的哈希码。
- 如果equals()方法判断两个对象相等,但hashCode()方法返回不同的哈希码,违反了一致性要求。
- 哈希表存储:
- 基于哈希表的集合(如HashMap、HashSet)使用hashCode()方法来确定对象在内部数据结构中的存储位置。
- 当你将对象添加到哈希表中时,哈希表使用对象的hashCode()方法来确定存储位置。
- 当你尝试从哈希表中检索对象时,哈希表使用hashCode()方法来快速定位对象的存储位置。
- 如果你只重写了equals()方法而没有重写hashCode()方法,哈希表将无法正确找到对象的存储位置,从而导致检索失败或无法正常工作的哈希表。
如果你不覆盖hashCode()方法,可能会导致以下问题:
- 对象在基于哈希表的集合中的存储位置将会发生变化,甚至可能无法正确找到对象。
- 在使用哈希表的集合类(如HashMap、HashSet)时,无法准确检索或删除对象。
- 相等的对象可能会被哈希表中存储多次,违反了集合中元素唯一性的要求。
因此,为了保持一致性、正确的哈希表存储以及符合Java规范,当你重写equals()方法时,总是应该同时重写hashCode()方法,以确保对象能够正确地在哈希表中存储、检索和比较。
5、什么是哈希表及其存储流程(2的图解)
zy:提高效率,避免重复,准确快速查找