为什么每次运行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() );
}
控制台上会有不同的打印值。 为何不一致?
答案 0 :(得分:3)
“不要求哈希值在不同的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
public static void main( String[] args ) {
System.out.println( test.A.hashCode() );
System.out.println( test.A.hashCode() );
}
此代码现在将生成相同的hashCode。
答案 1 :(得分:3)
如果您希望每次都使用相同的值,请使用.ordinal()
甚至更好,请像您一样使用getValue()
。您可以从默认值中覆盖hashCode(),为其提供一个基于对象创建方式的数字。
答案 2 :(得分:2)
javadocs明确指出。从对象c中的哈希码方法的javadocs 类
尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但JavaTM编程语言不需要此实现技术。)
因此,在您的演示代码的不同运行中,内部地址可能会有所不同,因此您看到不同的值是完全正常的。
根据您的需要,如果您希望hashcode()方法在jvm调用中返回相同的值,则应覆盖该方法以返回自定义值。但是,如果要在基于散列的集合中使用该对象(增加哈希冲突的可能性),您应该知道这可能是灾难性的。
答案 3 :(得分:0)
也许一些JVM实现基本上返回Enum.ordinal()
(这也会很好hashCode
) - 但它不能有效地改变任何东西。 hashCode()
值不必在执行或JVM之间保持一致。唯一需要的合同在Object.hashCode()
的JavaDocs中描述 - 它是Object
中enum
中使用的实现。
另请注意,实现界面与hashCode()
:
public class TestEnum {
public static void main(String[] args) {
System.out.println(Silly.B.hashCode());
System.out.println(Silly.C.hashCode());
System.out.println(Silly.D.hashCode());
}
}
enum Silly {
B, C, D
}
此程序还会在每次运行时返回不同的hashCode()
。
答案 4 :(得分:0)
Enum.hashCode
未定义为返回任何特定值(除遵守Object.hashCode
的规则之外),并且常见实现不会做任何特殊操作。
为什么呢?如果您使用HashSet
中的枚举(仅限)或HashMap
中的密钥,那么您应该使用优化的EnumSet
或EnumMap
。现在考虑枚举是否与HashSet
中的其他类型一起使用。也许你有一些“标准选项”来实现一个接口,但其他人可以自带选项。任何无国籍人都会这样做。一个HashSet
中的多个枚举类型。如果Enum
使用了常数作为哈希值,那么您将遇到常见的冲突。使用System.identityHashCode
可以稳健地减少冲突。
public interface Option {
}
public enum StandardOptions implements Option {
A, B, C
}
enum CustomOptions {
P, Q, R
}
enum MoreOptions {
X, Y, Z
}
Set<Option> options = new HashSet<>();
options.add(A);
options.add(P);
options.add(X);
我们真的不想要A.hashCode() == P.hashCode() == X.hashCode()
。