This week's book giveaway is in the Agile and other Processes forum.
We're giving away four copies of The Mikado Method and have Ola Ellnestam and Daniel Brolund on-line!
See this thread for details.
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
Register / Login


Win a copy of The Mikado Method this week in the Agile and other Processes forum!
JavaRanch » Java Forums » Java » Java in General
Reply 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: 19216

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
How To Ask Questions How To Answer Questions
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 32654
    
    4
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: 32654
    
    4
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: 3791
    
    1

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: 19216

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: 3047
    
    1

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: 32654
    
    4
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: 19216

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://ej-technologies/jprofiler - if it wasn't for jprofiler, we would need to run our stuff on 16 servers instead of 3.
 
subject: hash code for enum and long field combined
 
Similar Threads
Issue with assigning enum instance variable
How to define constants for several classes?
retrieve enumeration datatype into jsp
Instance variables in enums
is enum type serializable by default?