
equals()
and hashCode()
in Java are two fundamental method which is declared in Object class and part or core Java library.
If you have any one of below concerns in Java then you are at right place.
- Java Practices -> Implementing equals
- override – Overriding equals and hashCode in Java
- How to override equals() method in java
- How to override hashCode() method in java
- How to override equals and hashCode method in Java
- How and Why to Override the equals Method in Java
- Why always override hashcode() if overriding equals()?
Let’s take a look at simple example to understand first Reference Equality
and Logical Equality
. The equality operator (==) compares the references (addresses in memory) of the two Strings as two different numbers – this is known as Reference equality
.
Logical equality
compares the data of the objects instead of the value of the references.
package com.crunchify.tutorials; /** * @author Crunchify.com */ public class CrunchifyLogicalVsReferenceEqality { public static void main(String[] args) { String strA = new String("eBay"); String strB = new String("eBay"); String strC = new String("Paypal"); // Create a String reference and assign an existing String's reference to it // so that both references point to the same String object in memory. String strD = strA; // Print out the results of various equality checks // Reference Equality System.out.println("Reference Equality Result:"); System.out.println(strA == strB); System.out.println(strA == strC); System.out.println(strA == strD); // Logical Equality System.out.println("\nLogical Equality Result:"); System.out.println(strA.equals(strB)); System.out.println(strA.equals(strC)); System.out.println(strA.equals(strD)); } }
Output:
Reference Equality Result: false false true Logical Equality Result: true false true
hashCode and equals are closely related :
- if you override equals, you must override hashCode.
- hashCode must generate equal values for equal objects.
- equals and hashCode must depend on the
same set of significant fields
. You must use the same set of fields in both of these methods. You are not required to use all fields. For example, a calculated field that depends on others should very likely be omitted fromequals
andhashCode
.
When implementing equals, fields are compared differently, according to their type:
- object fields, including collections : use equals
- type-safe enumerations : use either equals or == (they amount to the same thing, in this case)
- possibly-null object fields : use both == and equals
- array fields : use
Arrays.equals
- primitive fields other than float or double : use ==
float
: convert to int usingFloat.floatToIntBits,
then use ==double
: convert to long usingDouble.doubleToLongBits
, then use ==
Implementing hashCode :
- 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
It is a popular misconception that hashCode provides a unique identifier for an object. It does not.
By general contract, the equals()
method in Java must be reflexive, symmetric, transitive, consistent, and any non-null reference must return false. In other words, for arbitrary values of a, b, and c, the following tests must always pass:
/ reflexive property assertTrue( a.equals(a) ); // symmetric property assertTrue( a.equals(b) == b.equals(a) ); // transitive property if ( a.equals(b) && b.equals(c) ) { assertTrue( a.equals(c) ); } // consistency property assertTrue( a.equals(b) == a.equals(b) ); // non-null property assertFalse( a.equals(null) );
For the Best practice use below steps to implement your equals() method:
- Use this == that to check reference equality
- Use
instanceof
to test for correct argument type - Cast the argument to the correct type
- Compare significant fields for equality
Here is a Complete Example.
CrunchifyImplementEqualsHashCode.java
package crunchify.com.tutorials; /** * * @author Crunchify.com * How to Override equals() method in Java? * How to Override hasCode() method in Java? * version:1.2 * */ public class CrunchifyImplementEqualsHashCode { public static void main(String[] args) { CrunchifyImplementEqualsHashCode crunchifyTest = new CrunchifyImplementEqualsHashCode(); Crunchify one = new Crunchify(1); Crunchify two = new Crunchify(1); crunchifyTest.test1(one, two); Crunchify three = new Crunchify(1); Crunchify four = new Crunchify(2); crunchifyTest.test2(three, four); } public void test1(Crunchify one, Crunchify two) { if (one.equals(two)) { System.out.println("Test1: One and Two are equal"); } else { System.out.println("Test1: One and Two are not equal"); } } public void test2(Crunchify three, Crunchify four) { if (three.equals(four)) { System.out.println("Test2: Three and Four are equal"); } else { System.out.println("Test2: Three and Four are not equal"); } } } class Crunchify { private int value; Crunchify(int val) { value = val; } public int getValue() { return value; } // The method does override or implement a method declared in a supertype. @Override public boolean equals(Object o) { // null check if (o == null) { return false; } // this instance check if (this == o) { return true; } // instanceof Check and actual value check if ((o instanceof Crunchify) && (((Crunchify) o).getValue() == this.value)) { return true; } else { return false; } } @Override public int hashCode() { int result = 0; result = (int) (value / 11); return result; } }
Eclipse Console Output:
Test1: One and Two are equal Test2: Three and Four are not equal