不同的 Enum HashCode 生成?
为什么每次运行java main时会有不同的hashCode值? 请看下面的示例代码。
interface testInt{
public int getValue();
}
enum test implements testInt{
A( 1 ),
B( 2 );
private int value;
private test( int value ) {
this.value = value;
}
public int getValue() {
return this.value;
}
}
每次运行时,
public static void main( String[] args ) {
System.out.println( test.A.hashCode() );
}
控制台上都会有不同的打印值。 为什么会出现这样的不一致呢?
Why there are different hashCode values for each time you run a java main?
Look the example code below.
interface testInt{
public int getValue();
}
enum test implements testInt{
A( 1 ),
B( 2 );
private int value;
private test( int value ) {
this.value = value;
}
public int getValue() {
return this.value;
}
}
For each time you run,
public static void main( String[] args ) {
System.out.println( test.A.hashCode() );
}
there will be different printed values on the console.
Why that inconsistency?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您每次都想要相同的值,请使用
.ordinal()
,甚至更好,请像您一样使用getValue()
。您可以覆盖默认值的 hashCode() ,即根据对象的创建方式为其提供一个数字。If you want the same value each time, use
.ordinal()
or even better, usegetValue()
like you have. You can override hashCode() from the default which is to give it a number which is based on the way the object was created.“不要求散列值在不同的 Java 实现之间保持一致,甚至在同一程序的不同执行运行之间也不要求散列值保持一致。”
http://en.wikipedia.org/wiki/Java_hashCode%28%29
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#hashCode%28%29
此代码现在将生成相同的 hashCode 。
"There's no requirement that hash values be consistent between different Java implementations, or even between different execution runs of the same program."
http://en.wikipedia.org/wiki/Java_hashCode%28%29
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#hashCode%28%29
This code will now produce same hashCode.
javadoc 明确指出了这一点。来自对象 c 中哈希码方法的 javadoc
班级
因此,在演示代码的不同运行中,内部地址可能会有所不同,因此它是完美的您看到不同的值是正常的。
根据您的需要,如果您希望 hashcode() 方法在 jvm 调用之间返回相同的值,您应该重写该方法以返回自定义值。但是,您应该知道,如果要在基于哈希的集合中使用该对象(哈希冲突的可能性增加),这可能会是灾难性的。
The javadocs clearly states that. From the javadocs for the hash code method in Object c
class
So across different runs of your demo code, the internal address can vary and hence it is perfectly normal for you to see different values.
Depending on your needs, if you want the hashcode() method to return the same value across jvm invocations, you should override the method to return the custom value. However, you should know this could be catastrophic if the object is to be used in hash based collections ( increased chances of hash collision).
也许某些 JVM 实现基本上返回
Enum.ordinal()
(这也会成为很棒的hashCode
) - 但它不会有效地改变任何东西。hashCode()
值不必在执行或 JVM 之间保持一致。唯一必需的约定在Object.hashCode()
- 它是enum
中使用的Object
中的实现。另请注意,实现接口与
hashCode()
无关:该程序还在每次运行时返回不同的
hashCode()
。Maybe some JVM implementations are basically returning
Enum.ordinal()
(which would make greathashCode
as well) - but it wouldn't effectively change anything.hashCode()
value don't have to be consistent across executions or JVMs. The only required contract is described in the JavaDocs ofObject.hashCode()
- and it is the implementation inObject
that is used inenum
.Also note that implementing an interface has nothing to do with
hashCode()
:This program also returns different
hashCode()
s on every run.Enum.hashCode
未定义为返回任何特定值(除了遵守Object.hashCode
的规则),并且常见实现不会执行任何特殊操作。为什么?如果您(仅)在
HashSet
中使用枚举或作为HashMap
中的键,那么您应该使用优化的EnumSet
或EnumMap
。现在考虑枚举是否要与HashSet
中的其他类型一起使用。也许您有一些“标准选项”来实现接口,但其他人可以提供自己的选项。任何无状态的东西都可以。一个HashSet
中包含多个枚举类型。如果Enum
使用序数作为哈希值,那么您将遇到常见的冲突。使用 System.identityHashCode 可以稳健地减少冲突。我们真的不想要
A.hashCode() == P.hashCode() == X.hashCode()
。Enum.hashCode
is not defined to return any specific values (other than obeying the rules ofObject.hashCode
), and common implementations don't do anything special.Why? If you were using the enums (only) in a
HashSet
or as a key in aHashMap
, well you should instead be using the optimisedEnumSet
orEnumMap
. Now consider if the enum was to be used alongside other types in aHashSet
. Perhaps you have some "standard options" to implement an interface, but others can come along with their own options. Anything stateless will do. Multiple enum types in oneHashSet
. IfEnum
had used ordinals for the hash value, then you will have common collisions. UsingSystem.identityHashCode
reduces collisions in a robust manner.We really don't want
A.hashCode() == P.hashCode() == X.hashCode()
.