Bit-shifting in Effective Java hashCode() implementation

Basically it XORs the top 32 bits of a long with the bottom 32 bits. Here’s an exploded version:

// Unsigned shift by 32 bits, so top 32 bits of topBits will be 0,
// bottom 32 bits of topBits will be the top 32 bits of l
long topBits = l >>> 32;

// XOR topBits with l; the top 32 bits will effectively be left
// alone, but that doesn't matter because of the next step. The
// bottom 32 bits will be the XOR of the top and bottom 32 bits of l
long xor = l ^ topBits;

// Convert the long to an int - this basically ditches the top 32 bits
int hash = (int) xor;

To answer your comment: you have a long value which has to be converted into an int to be part of the hash (the result has to only be 32 bits). How are you going to do that? You could just take the bottom 32 bits – but then that means changes in only the top 32 bits would be ignored, which wouldn’t make it a very good hash. This way, a change in a single bit of input always results in a change of a single bit of the hash. Admittedly you can still get collisions easily – change both bits 7 and 39, for example, or any other pair of bits 32 positions apart – but that’s bound to be the case, given that you’re going from 264 possible values to 232.

Leave a Comment