Software Engineering for Smart Data Analytics & Smart Data Analytics for Software Engineering
“This class overrides equals(Object), but does not override hashCode(). Therefore, the class may violate the invariant that equal objects must have equal hashcodes.” – 2013-10-13
While overriding the equals(Object) method, its a necessity to override the hashCode() method as well. As according to the Java contract equals and hashCode are bounded together with a joint contract specifying that if two objects are equal using the equals(Object) method then they mush have identical hashcode value.
This has to be followed as objects which are considered equal, should be able to used interchangeably in Collections such as HashMap. The below code shows an example where if you, don't override the hashcode method, the objects returning true in equals(Obejct) cannot retrieve values from hashMap interchangeably. The corrected code overrides hashCode and return the same value for both the objects, thus making it possible to retrieve information from Collections with object returning true for equals method.
import java.util.HashMap; public class HE_EQUALS_NO_HASHCODE { public static void main(String[] args) { Moof moof1 = new Moof(8); Moof moof2 = new Moof(8); HashMap<Moof, String> hashMap = new HashMap<Moof, String>(); //Comparing moof1 and moof2 via overridden equals method System.out.println(moof1.equals(moof2)); //Output true //Entering a value in the map using moof1 object hashMap.put(moof1, "Should Return with Moof2"); //Retrieving the value from the map using moof2 object System.out.println(hashMap.get(moof2)); // Output : null } } class Moof{ private int val; public Moof(int val){ this.val = val; } public int getVal() { return val; } public void setVal(int val) { this.val = val; } /* * @see java.lang.Object#equals(java.lang.Object) * @parameters Object * @return boolean * @description To make 2 objects equal whose instance variable val are equal. */ public boolean equals(Object obj){ if(obj instanceof Moof && this.val == ((Moof)obj).val){ return true; } return false; } }
import java.util.HashMap; public class HE_EQUALS_HASHCODE { public static void main(String[] args) { MoofWithHashCode moof1 = new MoofWithHashCode(8); MoofWithHashCode moof2 = new MoofWithHashCode(8); HashMap<MoofWithHashCode, String> hashMap = new HashMap<MoofWithHashCode, String>(); // Comparing moof1 and moof2 via overridden equals method System.out.println(moof1.equals(moof2)); // Output true // Entering a value in the map using moof1 object hashMap.put(moof1, "Should Return with Moof2"); // Retrieving the value from the map using moof2 object System.out.println(hashMap.get(moof2)); // Output : Should Return with Moof2 } } class MoofWithHashCode { private int val; public MoofWithHashCode(int val) { this.val = val; } public int getVal() { return val; } public void setVal(int val) { this.val = val; } /* * @see java.lang.Object#equals(java.lang.Object) * @parameters Object * @return boolean * @description To make 2 objects equal whose instance variable val are * equal. */ public boolean equals(Object obj) { if (obj instanceof MoofWithHashCode && this.val == ((MoofWithHashCode) obj).val) { return true; } return false; } /* * @see hashCode() * @parameters none * @return int * @description returns hashcode for the Integer val. * equal. */ public int hashCode(){ return new Integer(this.val).hashCode(); } }