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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1959948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 01:48:47  来源:igfitidea点击:

how does the hashCode() method of java works?

javahashobjecthashtable

提问by Hellnar

I am curious how java generates hash values by using hashCode()method of the Object API ?

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

采纳答案by MarkPowell

Java doesn't generate hashCode(), i.e. nothing automatic is happening here. However, Objectgenerates a HashCode based on the memory address of the instance of the object. Most classes (especially if you are going to use it in any of the CollectionAPI) should implement their own HashCode (and by contract their own equals method).

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

回答by Pascal Thivent

The hashCode()of Objectis actually a native method and the implementation is actually not pure Java. Now, regarding the how it works, this answer from Tom Hawtindoes a great job at explaining it:

hashCode()Object实际上是一个本地方法和实现其实不是纯Java。现在,关于它的工作原理,Tom Hawtin 的这个答案在解释它方面做得很好:

Many people will claim that Object.hashCodewill return the address of the object representation in memory. In modern implementations objects actually move within memory. Instead an area of the object header is used to store the value, which may be lazily derived from the memory address at the time that the value is first requested.

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

The whole answer is actually worth the read.

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

回答by JCasso

According to Java Platform API documentation, the calculation of hashcode is based on 32-bit internal JVM address of the Object.

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

It is true that the object moves during execution (AFAIK the only reason is garbage collector). But hashcode does not change.

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

So when you have an object like this

所以当你有一个这样的对象时

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

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

Person person3 = person2;

In this case person1.hashCode will not be equal to person2.hashCode because the memory addresses of these two objects are not the same.

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

But person2.hashCode will be equal to person3 because they are pointing to the same object.

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

So if you need to use hashCode method for your objects you must implement it yourself.

所以如果你需要对你的对象使用 hashCode 方法,你必须自己实现它。

By the way String.hashCode implementation is different. It is something like this: (C# syntax)

顺便说一下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;
}

edit:No overflow check is done here, so the hashCode may be positive or negative.

编辑:这里没有做溢出检查,所以 hashCode 可能是正数或负数。

回答by fastcodejava

Java does not generate meaningful hashCodefor you, it is your job as a programmer to generate a useful hashCode. The default hashCodeis just the memory location.

Java 不会hashCode为您生成有意义的文件,您作为程序员的工作是生成有用的hashCode. 默认hashCode值只是内存位置。

回答by Peter Lawrey

The Object.hashCode() uses the System.identityHashCode() which is based on an id number for a given object.

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

回答by Denis Stepanov

The HashCode () function has several options for creating a hash code. It sets the JVM startup parameter. Function, which create hashCode() written on C++, and you can see code here

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

  • HashCode==0:Simply returns random numbers with no relation to where in memory the object is found. As far as I can make out, the global read-write of the seed is not optimal for systems with lots of processors.
  • HashCode==1:Counts up the hash code values, not sure at what value they start, but it seems quite high.
  • HashCode==2:Always returns the exact same identity hash code of 1. This can be used to test code that relies on object identity. The reason why JavaChampionTest returned Kirk's URL in the example above is that all objects were returning the same hash code.
  • HashCode==3:Counts up the hash code values, starting from zero. It does not look to be thread safe, so multiple threads could generate objects with the same hash code.
  • HashCode==4:This seems to have some relation to the memory location at which the object was created.
  • HashCode>=5:This is the default algorithm for Java 8 and has a per-thread seed. It uses Marsaglia's xor-shift scheme to produce pseudo-random numbers.
  • HashCode==0:简单地返回与对象在内存中的位置无关的随机数。据我所知,种子的全局读写对于具有大量处理器的系统来说并不是最佳的。
  • HashCode==1:计算哈希码值,不确定它们从什么值开始,但似乎相当高。
  • HashCode==2:始终返回与 1 完全相同的身份哈希码。这可用于测试依赖于对象身份的代码。JavaChampionTest 在上例中返回 Kirk 的 URL 的原因是所有对象都返回相同的哈希码。
  • HashCode==3:从零开始计算哈希码值。它看起来不是线程安全的,因此多个线程可以生成具有相同哈希码的对象。
  • HashCode==4:这似乎与创建对象的内存位置有某种关系。
  • HashCode>=5:这是 Java 8 的默认算法,并且具有每线程种子。它使用 Marsaglia 的 xor-shift 方案来产生伪随机数。

The information was taken from here

信息是从这里获取的

回答by Johnny

The hashCodemethod outputs a numeric value. The hashcode for an object is always the same if the object doesn't change. It's important to mention, that it's not have to be unique.

hashCode方法输出一个数值。如果对象没有改变,对象的哈希码总是相同的。值得一提的是,它不一定是独一无二的。

Default implementation of hashCode() is given in such a way that it returns the Hash Code number for the object based on the address of the object. JVM automatically generates this unique number based on the address of the object.

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

If two objects are at same memory location (the same object referred by two reference variable) then hashcode number for both will be same but if two objects reside at different memory location then hashcode number for both object will be different.

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

You probably asked the question because you need to override the method. But, when to override it?

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

Default implementation of hashCode() method returns hashcode number (unique identity of object) based on the address of the object. But if my application requires to uniquely identify the objects based on some different parameter (rather than address of the object), then I should override hashCode() method and should give implementation as per the requirement.

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

An important note from Effective Javaabout the topic:

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

enter image description here

在此处输入图片说明

For more, check out this Java hashcode example.

有关更多信息,请查看此Java 哈希码示例