不同的Enum HashCode生成?

时间:2012-02-24 18:18:12

标签: java interface enums 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() );
}

控制台上会有不同的打印值。 为何不一致?

5 个答案:

答案 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中描述 - 它是Objectenum中使用的实现。

另请注意,实现界面与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中的密钥,那么您应该使用优化的EnumSetEnumMap。现在考虑枚举是否与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()