Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
hashCode()是如何在Java中实现的_Java_Hash - Fatal编程技术网

hashCode()是如何在Java中实现的

hashCode()是如何在Java中实现的,java,hash,Java,Hash,如何实施 我的假设是,它使用对象内存位置作为运行哈希函数的初始编号(种子)。然而,情况并非如此 我也看过,但它没有回答我的问题 是的,我可以下载SDK,但在我下载并查看代码之前,可能其他人已经知道了 谢谢:) 编辑: 我知道它应该被重写等等,所以请尽量停留在主题上:)我假设您谈论的是hashCode的对象实现,因为该方法可以而且应该被重写 它依赖于实现。对于Sun JDK,它基于对象的内存地址。当然它是特定于实现的,但通常会延迟计算对象的哈希代码并存储在对象头中。奇怪的事情是用头来保持它们的小,

如何实施

我的假设是,它使用对象内存位置作为运行哈希函数的初始编号(种子)。然而,情况并非如此

我也看过,但它没有回答我的问题

是的,我可以下载SDK,但在我下载并查看代码之前,可能其他人已经知道了

谢谢:)

编辑:
我知道它应该被重写等等,所以请尽量停留在主题上:)

我假设您谈论的是
hashCode
对象
实现,因为该方法可以而且应该被重写


它依赖于实现。对于Sun JDK,它基于对象的内存地址。

当然它是特定于实现的,但通常会延迟计算对象的哈希代码并存储在对象头中。奇怪的事情是用头来保持它们的小,同时允许复杂的锁定算法

在OpenJDK/Oracle JVM中,计算初始哈希代码的常用方法是基于第一次请求时的内存地址。对象在内存中移动,因此每次使用地址都不是一个好的选择。散列代码不是实际地址-通常是8的倍数,这对于在散列表中使用straight(特别是2倍大小的幂)不是很好。注意:标识哈希代码不是唯一的


HotSpot具有构建时选项,可以始终使用零或使用安全随机数生成器(SRNG)进行测试。

hashcode()函数的实现因对象而异。如果您想知道某个特定类如何实现hashcode(),则必须查找该类。

类对象定义的hashcode方法为不同的对象返回不同的整数。这可以通过将对象的内部地址转换为整数来实现(但该标准不要求这种实现样式)。为了支持哈希表(equal和hashCode),重写hashCode的新类变得很有趣:

不,不,不。此线程中的所有答案都是错误的,或者至少部分正确

第一:
Object.hashCode()
是本机方法,因此它的实现完全依赖于JVM。它可能在和其他VM实现(如或)之间有所不同

如果你问:

如何在Java中实现
hashCode()

那么答案是:这取决于您使用的虚拟机

假设您使用的是Oracle的默认JVM,即HotSpot,那么我可以告诉您HotSpot有六个
hashCode()
实现。您可以通过命令行使用运行JVM的
-XX:hashCode=n
标志来选择它,其中
n
可以是:

0–停车场磨坊RNG(默认)
1-f(地址、全球联合声明)
2–常数1
3–串行计数器
4–对象地址
5–螺纹局部异或移位
以上内容摘自

如果您仔细研究一下热点源代码,您可能会发现以下代码片段:

if (hashCode == 0) {
  value = os::random();
} else {
  ...
os::random()
只是Park-Miller伪随机生成器算法的实现

就这些内存地址没有任何概念。尽管其他两种实现,
1
4
使用对象的内存地址,但默认的实现不使用它。
Object.hashCode()
是基于对象地址的概念在很大程度上是一种错误,不再是这样


我知道在
Object#hashCode()
JavaDoc中,我们可以阅读:

(…)这通常是通过将对象的内部地址转换为整数来实现的,但是Java不需要这种实现技术™ 编程语言


但是它已经过时,并且会产生误导。

来自您自己的链接:“这通常是通过将对象的内部地址转换为整数来实现的,但是Java(TM)编程语言不需要这种实现技术。”当然,这由实现自行决定,但这应该证实您对Oracle实施的假设。为什么你说不是这样呢?如果你看到对象类-public native int hashCode(),它有自己的本机实现@当物体在记忆中移动时会发生什么?我认为这有点误导。对象在内存中移动,但有一个稳定的标识哈希代码。@TomHawtin解释了我问这个问题的原因;这似乎是一个很好的种子(比如乘以素数),但当你意识到物体在内存中移动后。。。IDKDown投票有两个原因。首先:通常不需要重写
hashCode
。第二:Sun JDK的默认值是伪随机数,而不是对象的内存地址。您可以看到我的代码以了解一点。@Adrian哈希代码是稳定的(尽管是随机的),因为在第一次计算后,结果将存储在对象的头中,并在后续调用hashCode()时返回。8的倍数可以乘以一个素数,以获得更好的哈希值number@Adrian它仍然是8的倍数。事实上,它被改变了。你只是部分正确。确实,它是特定于实现的。但是错误的是,通常的方法是基于内存地址的。这是一个非常常见的错误-我不是在责备你,因为即使是
对象#hashCode()
中的javadoc也会误导你。从历史上看,是的。实际上不是:)