Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What issues should be considered when overriding equals and hashCode in Java?

What issues / pitfalls must be considered when overriding equals and hashCode?

like image 393
Matt Sheppard Avatar asked Aug 26 '08 08:08

Matt Sheppard


People also ask

What is rule regarding overriding equals and hashCode method?

if a class overrides equals, it must override hashCode. when they are both overridden, equals and hashCode must use the same set of fields. if two objects are equal, then their hashCode values must be equal as well. if the object is immutable, then hashCode is a candidate for caching and lazy initialization.

When and why should you override hashCode and equals?

"If two objects are equal using Object class equals method, then the hashcode method should give the same value for these two objects." So, if in our class we override equals() we should override hashcode() method also to follow this rule.

Why we need to override hashCode when overriding equals in Java with example?

Case 1: Overriding both equals(Object) and hashCode() method Whenever it(hashcode) is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified.

What happens if we do not override hashCode () and equals () in HashMap?

If you don't override hashcode() then the default implementation in Object class will be used by collections. This implementation gives different values for different objects, even if they are equal according to the equals() method.


1 Answers

The theory (for the language lawyers and the mathematically inclined):

equals() (javadoc) must define an equivalence relation (it must be reflexive, symmetric, and transitive). In addition, it must be consistent (if the objects are not modified, then it must keep returning the same value). Furthermore, o.equals(null) must always return false.

hashCode() (javadoc) must also be consistent (if the object is not modified in terms of equals(), it must keep returning the same value).

The relation between the two methods is:

Whenever a.equals(b), then a.hashCode() must be same as b.hashCode().

In practice:

If you override one, then you should override the other.

Use the same set of fields that you use to compute equals() to compute hashCode().

Use the excellent helper classes EqualsBuilder and HashCodeBuilder from the Apache Commons Lang library. An example:

public class Person {     private String name;     private int age;     // ...      @Override     public int hashCode() {         return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers             // if deriving: appendSuper(super.hashCode()).             append(name).             append(age).             toHashCode();     }      @Override     public boolean equals(Object obj) {        if (!(obj instanceof Person))             return false;         if (obj == this)             return true;          Person rhs = (Person) obj;         return new EqualsBuilder().             // if deriving: appendSuper(super.equals(obj)).             append(name, rhs.name).             append(age, rhs.age).             isEquals();     } } 

Also remember:

When using a hash-based Collection or Map such as HashSet, LinkedHashSet, HashMap, Hashtable, or WeakHashMap, make sure that the hashCode() of the key objects that you put into the collection never changes while the object is in the collection. The bulletproof way to ensure this is to make your keys immutable, which has also other benefits.

like image 144
18 revs, 10 users 77% Avatar answered Oct 12 '22 14:10

18 revs, 10 users 77%