8

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?

Víctor Hugo
  • 233
  • 1
  • 10

5 Answers5

4

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

jn1kk
  • 5,012
  • 2
  • 45
  • 72
  • Ok, but, that only happens if you have an enum which implements an interface. – Víctor Hugo Feb 24 '12 at 18:24
  • Not necessarily. If you are comparing to producing hashcode of a string (or something else) between program execution, the fact that they generate the same code may be a coincidence. – jn1kk Feb 24 '12 at 18:26
  • I guess coincidence is not the right word here. It really returns the same hashCode value for enums that doesnt implement any interface. That's what pointed me here. – Víctor Hugo Feb 24 '12 at 18:33
4

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.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Yes, i'm using now getValue as a solution. Just created the post to see why different hashCodes when implementing an interface. Thanks. – Víctor Hugo Feb 24 '12 at 18:58
2

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

Scorpion
  • 3,938
  • 24
  • 37
  • As I said. What brought me here was the fact of, simple enums, in my Oracle JVM7, was returning the same hashCode on different runs. But when swapped to specialized enum, the hashcode was different for every run. – Víctor Hugo Feb 24 '12 at 18:54
0

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.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • Ok, Silly.B.hashCode, would return the same and not different hasCodes. If implementing an interface has nothing to do with hashCode, why that happens? Do u see where i'm coming? Silly.B.hashCode is equals on different runs, but if u make Silly implements a simple interface, then there will be different hashCodes for Silly.A – Víctor Hugo Feb 24 '12 at 18:56
  • @VíctorHugo: which JVM are you using? On 1.6.0_26-b03 it sometimes return the same and sometimes different values, but for sure they aren't the same all the time... – Tomasz Nurkiewicz Feb 24 '12 at 19:13
0

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

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305