Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the preferred way of implementing hashCode()?

Tags:

java

hashcode

Sometimes I need to implement an obj's hashCode() method by combining the hashCodes of its several instance members. For example, if the combinational obj has members a, b, and c, I often see ppl implement it as


int hashCode(){
   return 31 * 31 * a.hashCode() + 31 * b.hashCode() + c.hashCode();
}

Where does this magic number 31 come from? Is it the length of 4-bytes or just a prime number?

Is there any other preferred/standard way of implementing hashCode()?

like image 653
dolaameng Avatar asked Oct 06 '10 03:10

dolaameng


People also ask

What is the use of hashCode() method in Java?

They use hashCode () method to check hash values. The default implementation of hashCode () in Object class returns distinct integers for different objects. Sometimes, we have to implement hashCode method in our program. A Name instance consists of a first name and a last name.

What is the difference between equals () and hashCode () methods?

The hashcode () method returns the same hash value when called on two objects, which are equal according to the equals () method. And if the objects are unequal, it usually returns different hash values. It returns the hash code value for the given objects.

What are the guidelines for implementing hashCode?

When implementing hashCode: Use a the same fields that are used in equals (or a subset thereof). Better not include mutable fields. Consider not calling hashCode on collections. Use a common algorithm unless patterns in input data counteract them.

What is hashing principle in Java?

In Java hashing principle stands behind some popular collections, such as HashMap, HashSet and HashTable . Every Java object has the hashCode () and equals () methods inherited from Object class. To get a good working equality mechanism, you’d better override hashcode () and equals () methods for your own classes.


3 Answers

See Effective Java's recipe. It's just the best source, hands down.

The use of a prime number is just to try to get a reasonably good distribution without knowing the domain. It will take a while to overflow to the same value. The value 31 is pretty arbitrary if I recall correctly.

According to Bloch (he uses 17 as an initial value and 37 as the constant multiplier):

A nonzero initial value is used (...) so the hash value will be affected by initial fields whose hash value (...) is zero. If zero was used as the initial value (...) the overall hash value would be unaffected by any such initial fields, which could increase collisions. The value 17 is arbitrary.
...
The multiplier 37 was chosen because it is an odd prime. If it was even and the multiplication overflowed, information would be lost because multiplication by two is equivalent to shifting. The advantages of using a prime number are less clear, but it is traditional to use primes for this purpose.

like image 120
3 revs, 2 users 98% Avatar answered Oct 17 '22 20:10

3 revs, 2 users 98%


One good option is Guava's Objects.hashCode method. It takes any number of arguments and creates a hashcode based on them:

@Override public int hashCode() {
  return Objects.hashCode(a, b, c);
}
like image 6
ColinD Avatar answered Oct 17 '22 19:10

ColinD


Use HashCodeBuilder from Commons Lang:

public int hashCode() {
    return HashCodeBuilder.reflectionHashCode(this);
}

See the API for ways to do it without using reflection. You can tell it which fields to include, or which to ignore.

See also EqualsBuilder, for overriding an equals method.

like image 2
wmorgan Avatar answered Oct 17 '22 18:10

wmorgan