hashCode方法返回常量值的原因是什么?

huangapple go评论57阅读模式
英文:

Is there any reason for returning constant value from hashCode method?

问题

我对与Java.lang.Object中的hashCode方法广泛讨论的主题有一个相关问题。是否有任何理由在某些情况下从hashCode()返回一个常量值?

public int hashCode()
{
   return 3;
}

如果您找到了某篇文章或SO线程直接回答了我的问题,我会很感激。坦率地说,我找不到。

我的想法

来自docs.oracle.com object hashCode()(我知道在SO中引用了很多次):

>不要求如果两个对象根据equals(java.lang.Object)方法是不相等的,那么调用这两个对象的hashCode方法必须产生不同的整数结果。但是,程序员应该意识到,对于不相等的对象产生不同的整数结果可能会提高哈希表的性能。

因此,从理论上讲,hashCode()可以返回一个常量值。在我的想象中和我所读到的内容中,当使用例如HashMap时,所有对象都将被放置在同一个桶中。例如,假设1000个元素将被放置在完全相同的哈希桶中(换句话说,会有1000次碰撞),在最坏的情况下要找到特定的元素需要遍历这1000个元素。那么它将表现得类似于LinkedList集合(请纠正我如果我错了)。

基于以上情况,hashCode()可以像这样返回一个常量值,但这将破坏使用hash...集合获得的性能。那么在某些特定的情况下这样做有意义吗?

编辑
我找到了一个具体的例子,可以使用常量hashCode方法,基于Vlad Mihalcea的文章:How to implement equals and hashCode using JPA entity identifier(Hibernate)。hashCode在实体状态转换之间不同,因此它应该返回常量值。文章中的引用:

>当实体首次存储在Set中时,标识符为null。在实体被持久化后,标识符被分配给自动生成的值,因此hashCode不同。因此,实体在持久化后无法在Set中找到。

因此,这是一个实际的例子,但代价是性能。如果除了实体ID之外还有业务唯一的非null标识符,最好使用它以利用存储实体在多个Hash...桶中的优势。

英文:

I have a question related to extensively discussed topic about hashCode method from java.lang.Object. Simply is there any reason why I should in some use-case return a constant value from hashCode()?

public int hashCode()
{
   return 3;
}

If you found some article or SO thread which directly answers my question I'd appreciate it. Frankly speaking I couldn't.

My thoughts:

From docs.oracle.com object hashCode() (I know quoted many many times here in SO):

>It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables."

So in theory hashCode() can return a constant value. In my imagination and what I've read, all objects then will be placed in the same bucket when using for example HashMap. As an example lets say 1000 elements will be placed in exactly the same hash bucket (there will be 1000 collisions then in the other words) and to find specific one in the wrong case scenario that 1000 elements would have to be iterated. Then it will perform similarly to LinkedList collection (correct me if I am wrong please).

Basing on the above, hashCode() can return a constant value like, but it will destroy performance gained from using hash... collections. Is there any sense then to do it in some particular example?

EDIT:
I found one particular example for having constant hashCode method
basing on Vlad's Mihalcea article: How to implement equals and hashCode using JPA entity identifier, (Hibernate). HashCode differs between entity state transitions, hence it should return constant value. Quote from the article:

>When the entity was first stored in the Set, the identifier was null. After the entity was persisted, the identifier was assigned to a value that was automatically generated, hence the hashCode differs. For this reason, the entity cannot be found in the Set after it got persisted.

So there is a practical example, but as it is pointed out at the cost of performance. If there is a business unique not null identifier apart from entity id, it is better to use it in order to take an advantage of storing entities in the multiple Hash... buckets.

答案1

得分: 5

通常情况下,在重写 hashcode 时,绝不会返回静态成员。我以前从未这样做过,但我甚至能想象到的唯一可能的用例是单例模式,其中您期望运行时只有一个未延迟初始化的实例。这有点无用,因为如果设计类以使用单例模式,您就不应该需要使用 equals/hashcode。

英文:

Generally you would never return a static member when overriding hashcode. I've never done this before but the only possible use case I could even imagine would be singletons where you expect runtime to only ever have 1 instance that is not lazily initialized. This is kind of useless because if you design the class to use the singleton pattern you should never need to use equals/hashcode.

答案2

得分: 1

常数hashCode在你知道类只会有非常少的唯一实例,理想情况下只有1个时是有意义的。

例如,在实现代数数据类型单例设计模式时,就会出现这种情况。

在代数数据类型中,无参数数据类型的所有实例都相等。因此hashCode必须对所有实例返回相同的值。

在单例模式中,一个类只会有一个实例。因此hashCode返回什么值都无关紧要,它可以返回一个常数。

英文:

Constant hashCode makes sense when you know the class will have only very few unique instances, ideally only 1.

This situation arises for example when implementing algebraic data types, or the Singleton design pattern.

In algebraic data types, all instances of a parameterless data type are equal to each other. Therefore hashCode must return the same value for all instances.

In the Singleton pattern, a class will have only one instance. Therefore it doesn't matter what value hashCode returns, and it can return a constant.

huangapple
  • 本文由 发表于 2020年8月9日 04:57:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/63320164.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定