不同的 Enum HashCode 生成?

发布于 2025-01-08 12:25:39 字数 506 浏览 0 评论 0原文

为什么每次运行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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

你与昨日 2025-01-15 12:25:39

如果您每次都想要相同的值,请使用 .ordinal() ,甚至更好,请像您一样使用 getValue() 。您可以覆盖默认值的 hashCode() ,即根据对象的创建方式为其提供一个数字。

If you want the same value each time, use .ordinal() or even better, use getValue() 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.

辞别 2025-01-15 12:25:39

“不要求散列值在不同的 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 。

"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

public static void main( String[] args ) {
     System.out.println( test.A.hashCode() );
     System.out.println( test.A.hashCode() );
}

This code will now produce same hashCode.

冷弦 2025-01-15 12:25:39

javadoc 明确指出了这一点。来自对象 c 中哈希码方法的 javadoc
班级

在相当实用的情况下,Object 类定义的 hashCode 方法确实为不同的对象返回不同的整数。 (这通常是通过将对象的内部地址转换为整数来实现的,但 JavaTM 编程语言不需要这种实现技术。)

因此,在演示代码的不同运行中,内部地址可能会有所不同,因此它是完美的您看到不同的值是正常的。

根据您的需要,如果您希望 hashcode() 方法在 jvm 调用之间返回相同的值,您应该重写该方法以返回自定义值。但是,您应该知道,如果要在基于哈希的集合中使用该对象(哈希冲突的可能性增加),这可能会是灾难性的。

The javadocs clearly states that. From the javadocs for the hash code method in Object c
class

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)

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).

我们只是彼此的过ke 2025-01-15 12:25:39

也许某些 JVM 实现基本上返回 Enum.ordinal() (这也会成为很棒的 hashCode) - 但它不会有效地改变任何东西。 hashCode() 值不必在执行或 JVM 之间保持一致。唯一必需的约定在 Object.hashCode() - 它是 enum 中使用的 Object 中的实现。

另请注意,实现接口与 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()

Maybe some JVM implementations are basically returning Enum.ordinal() (which would make great hashCode 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 of Object.hashCode() - and it is the implementation in Object that is used in enum.

Also note that implementing an interface has nothing to do with 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
}

This program also returns different hashCode()s on every run.

旧瑾黎汐 2025-01-15 12:25:39

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()

Enum.hashCode is not defined to return any specific values (other than obeying the rules of Object.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 a HashMap, well you should instead be using the optimised EnumSet or EnumMap. Now consider if the enum was to be used alongside other types in a HashSet. 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 one HashSet. If Enum had used ordinals for the hash value, then you will have common collisions. Using System.identityHashCode reduces collisions in a robust manner.

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);

We really don't want A.hashCode() == P.hashCode() == X.hashCode().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文