当前位置: 首页 > 面试题库 >

Java如果未覆盖hashCode(),则对象的哈希码是什么?

左丘涵畅
2023-03-14
问题内容

如果未重写hashCode()方法,那么对Java中的任何对象调用hashCode()的结果是什么?


问题答案:

在HotSpot JVM中,默认情况下会在第一次调用时生成未重载Object.hashCodeSystem.identityHashCode随机数并将其存储在对象标头中。随后的调用Object.hashCodeSystem.identityHashCode仅从标头中提取此值。默认情况下,它与对象内容或对象位置没有共同点,只有随机数。此行为由-XX:hashCode=nHotSpot JVM选项控制,该选项具有以下可能的值:

  • 0:使用全局随机数发生器。这是Java 7中的默认设置。它的缺点是,来自多个线程的并发调用可能导致竞争状态,这将导致为不同的对象生成相同的hashCode。同样,在高度并发的环境中,由于争用(使用来自不同CPU内核的相同内存区域)可能导致延迟。
  • 5:使用一些线程局部异或移位随机生成器,它没有以前的缺点。这是Java 8中的默认设置。
  • 1:使用对象指针并混合一些在“世界停止”事件中更改的随机值,因此在世界停止事件(如垃圾回收)之间生成的hashCode是稳定的(用于测试/调试目的)
  • 2:始终使用1(用于测试/调试)
  • 3:使用自动递增编号(出于测试/调试的目的,还使用全局计数器,因此可能出现竞争和竞争条件)
  • 4:如有必要,请使用调整为32位的对象指针(用于测试/调试)

请注意,即使你设置了-XX:hashCode=4,hashCode也不会始终指向对象地址。对象可能会在以后移动,但是hashCode将保持不变。此外,对象地址分布不均(如果你的应用程序使用的内存不多,大多数对象将位于彼此附近),因此如果使用此选项,则最终可能会导致哈希表不平衡。



 类似资料:
  • 问题内容: 假设我创建了一个对象,该对象具有ID,firstName,lastName和email,用于实例变量和相应的setter / getter方法。如何,如果我不重写计算中时,它存储在集合对象的对象? 问题答案: 如果不重写hashcode(),则集合将使用Object类中的默认实现。即使根据equals()方法它们相等,此实现也会为不同的对象提供不同的值。 一些集合(例如HashSet,

  • 我有3个实体,学生,年级和班级。代码如下所示。这只是一个示例。 学生班级 学校班级: 等级等级: 所以我检查了hibernate文档中的hashcode和equals,它对于DB中存在的实体工作得非常好。我遇到的问题是,在保存到数据库之前,新的瞬态实体对象。我使用HashSet对学生和班级进行了单独的测试,如果它试图添加相同的对象,集合的大小不会增加。 这里我有一个新的成绩集,准备这个集并保存到数

  • 问题内容: 该程序将两个元素都添加到集合中。起初我很震惊,因为在添加设置方法时,调用了equals方法。 但是后来我覆盖了hashCode方法: 然后没有添加。这是令人惊讶的,因为Set和add()方法的Javadoc说它在添加到Set中时仅检查equals()。 这是add()的javadoc: 然后我意识到HashSet被实现为HashMap,并且在地图中,对象的hashCode用作键。因此,

  • 每当我使用eclipse'source'菜单覆盖hashcode()时,它会在类中生成以下代码 谁能解释一下为什么它要做所有这些计算(乘法和加法),为什么它不简单地返回 ?

  • 问题内容: 我对Java有一个小问题。如果我重写该方法,使得: 这将导致所有键具有相同的索引。是将它们放置在地图的链接列表结构中,还是仅包含替换了所有其他键的最后一个键? 问题答案: 假设您没有覆盖始终返回true 的方法,它们将放置在地图的链接列表结构中。不同的键可能具有相同的hashCode,但是如果所有键都具有相同的hashCode,则您的HashMap将成为链接列表,这首先使使用此结构的目

  • 问题内容: 我正在阅读Java 1.6 API提供的HashMap类的代码,无法完全理解以下操作的需要(位于put和get方法的主体中): 该方法具有以下主体: 通过对提供的哈希码执行位操作,可以有效地重新计算哈希。即使API声明如下,我也无法理解这样做的必要性: 这很关键,因为HashMap使用2的幂的哈希表,否则哈希表在低位无差异时会遇到冲突。 我确实知道键值参数存储在数据结构数组中,并且该数