aspose file tools*
The moose likes Java in General and the fly likes hash code for enum and long field combined Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "hash code for enum and long field combined" Watch "hash code for enum and long field combined" New topic
Author

hash code for enum and long field combined

B Nirvan
Ranch Hand

Joined: Oct 20, 2010
Posts: 82
I have an object whose primary identity consists of a combination of an Enum type and a long. What hashcode generation logic should I use for efficient fetching of the object from maps or some other functioning.

regards,
Nirvan
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19790
    
  20

The topic of creating efficient hashCode implementations warrants at least one book of its own; it's a very advanced topic.

What I usually do is something like this:
The prime is mostly 31, but I can't remember why. Probably because I've seen it being used a lot; even String uses it.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40052
    
  28
How about

. . . myEnum.hashCode() * 31 + (int)((myLong >> 0x20) ^ myLong) . . . ?

Assuming you only have those two fields. I can't remember whether ^ has a higher precedence than >> or vice versa.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40052
    
  28
It says in a book I have read, possibly Bruce Eckel's Thinking in Java™ 4/e, that i * 31 can be optimised to (i << 5) - i which is faster than multiplication.
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4490
    
    8

NetBeans will generate a hashCode() for you, based on the fields you want to use, and it uses a similar approach. I just tried it out and got this:

Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19790
    
  20

Almost the same approach: take the previous hash code, multiply by a prime number, and add a new part to it. The only difference is that my initial value is 0 instead of a prime number (7). 1 is also a sometimes used initial value.

The usual "rules" for calculating hash code parts:
- objects: (object == null ? 0 : object.hashCode())
- byte, char, short, int: the value itself
- float: Float.floatToIntBits(value)
- long: (int)(value ^ (value >>> 32)) (i.e. what Matthew already posted)
- double: Double.doubleToLongBits(value) to convert to long, then the long to hashCode computation
- boolean: use Boolean.valueOf(value).hashCode(). This (currently) returns 1231 for true, 1237 for false. Because Boolean.valueOf(boolean) always returns one of the two static final fields it won't add any memory usage.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3649
    
  17

Campbell Ritchie wrote:How about

. . . myEnum.hashCode() * 31 + (int)((myLong >> 0x20) ^ myLong) . . . ?

Assuming you only have those two fields. I can't remember whether ^ has a higher precedence than >> or vice versa.


Unary > Arithmetic > Comparison > Bitwise > Logical > Ternary > Assignment
These are broad categories I have memorized in order to remember the precedence.
Note that bitwise shifts are considered arithmetic, so they trump xor operations.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40052
    
  28
You are right; >> has a higher precedence than ^ so one of my pairs of () is redundant.
B Nirvan
Ranch Hand

Joined: Oct 20, 2010
Posts: 82
Whew,
It seems I will have to read some book before I get to fully understand all your replies. Meanwhile, I will follow Matthew's suggestion and let the netbeans produce the hashCode and equals. Here is the code generated by Netbeans. In the code the phoneType is the enum and donorId is long. I hope this is efficient.


Thanks for the replies.

regards,
Nirvan.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19790
    
  20

Wait what? That can't be right. donor is definitely not a long; it's being used as an Object (comparing against null, calling methods on it, etc). Is it perhaps a Long?
B Nirvan
Ranch Hand

Joined: Oct 20, 2010
Posts: 82
Hi Rob,
Sorry for being late to respond. Donor is definitely an object as you guessed, but it has a long id as donorId. The hashcode for it is also generated by netbeans. So in short the Phone Entity has effectively an Identity that is composed of PhoneType and DonorId (mapped as Donor in hibernate). The hashcode generation logic for Phone entity refers to the hashcode of Donor entity. So I think this must work correctly.

thanks and regards,
Nirvan
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: hash code for enum and long field combined