java的hashCode()方法是如何工作的?

时间:2009-12-24 22:35:16

标签: java hash object hashtable

我很好奇java如何使用Object API的hashCode()方法生成哈希值?

7 个答案:

答案 0 :(得分:24)

hashCode()的{​​{1}}实际上是一个本机方法,实现实际上不是纯Java。现在,关于它的工作原理,this answer from Tom Hawtin在解释它方面做得很好:

  

许多人会声称Object会在内存中返回对象表示的地址。在现代实现中,对象实际上在内存中移动而是使用对象标题的一个区域来存储该值,该值可能是在首次请求该值时从内存地址延迟导出的。

整个答案实际上值得一读。

答案 1 :(得分:10)

Java不生成hashCode(),即此处没有自动发生。但是,Object根据对象实例的内存地址生成HashCode。大多数类(特别是如果你要在任何Collection API中使用它)应该实现自己的HashCode(并通过契约自己的equals方法)。

答案 2 :(得分:5)

根据Java Platform API文档,hashcode的计算基于Object的32位内部JVM地址。

确实,对象在执行期间移动(AFAIK唯一的原因是垃圾收集器)。但哈希码不会改变。

所以当你有这样的对象时

Person person1 = new Person();
person1.setName("Alex");

Person person2 = new Person();
person2.setName("Alex");

Person person3 = person2;

在这种情况下,person1.hashCode将不等于person2.hashCode,因为这两个对象的内存地址不相同。

但是person2.hashCode将等于person3,因为它们指向同一个对象。

因此,如果您需要为对象使用hashCode方法,则必须自己实现它。

顺便说一句 String.hashCode实现不同。它是这样的:(C#语法)

public int hashCode(String str)
{
  int h = 0;

  for (int i = 0; i < str.Length; i++)
    h = (h * 31) + str[i];

  return h;
}

编辑:此处未进行溢出检查,因此hashCode可能为正数或负数。

答案 3 :(得分:4)

Object.hashCode()使用System.identityHashCode(),它基于给定对象的id号。

答案 4 :(得分:2)

HashCode()函数有几个用于创建哈希码的选项。它设置JVM启动参数。函数,它创建了用C ++编写的hashCode(),你可以看到代码here

  • HashCode == 0:只需返回与where无关的随机数 在内存中找到了对象。就我所知,全球化 对于有很多种子的系统,种子的读写不是最佳的 处理器。
  • HashCode == 1:计算哈希码值,不确定值是多少 他们开始了,但似乎很高。
  • HashCode == 2:始终返回完全相同的标识哈希码1。 这可用于测试依赖于对象标识的代码。该 JavaChampionTest在上面的例子中返回Kirk的URL的原因 是所有对象都返回相同的哈希码。
  • HashCode == 3:从零开始计算哈希码值。它 看起来不是线程安全的,因此可以生成多个线程 具有相同哈希码的对象。
  • HashCode == 4:这似乎与内存位置有一定关系 创建对象的位置。
  • HashCode&gt; = 5:这是Java 8的默认算法,并且有一个 每线程种子。它使用Marsaglia的xor-shift方案来制作 伪随机数。

该信息来自here

答案 5 :(得分:1)

Java不会为您生成有意义的hashCode,您作为程序员可以生成有用的hashCode。默认hashCode只是内存位置。

答案 6 :(得分:0)

hashCode方法输出一个数值。如果对象不变,则对象的哈希码始终相同。值得一提的是,它不必是唯一的。

hashCode()的默认实现以这样的方式给出:它根据对象的地址返回该对象的哈希码编号。 JVM根据对象的地址自动生成此唯一编号。

如果两个对象位于相同的内存位置(由两个引用变量引用的同一对象),则两个对象的哈希码号将相同,但是如果两个对象位于不同的内存位置,则两个对象的哈希码号将不同。

您可能会问这个问题,因为您需要覆盖该方法。但是,何时覆盖它?

hashCode()方法的默认实现根据对象的地址返回哈希码编号(对象的唯一标识)。但是,如果我的应用程序需要根据一些不同的参数(而不是对象的地址)唯一地标识对象,那么我应该重写hashCode()方法,并根据要求进行实现。

Effective Java关于该主题的重要说明:

enter image description here

有关更多信息,请查看此Java hashcode example