x Java Java 8 JUnit JSON
  • XML
  • JDBC Spring Boot Microservices React Contact Us

    How to implement equals() and hashcode() methods in Java ?


    1) Implementing equals() method

    In Java if you want to check that two objects are meaningfully equal, then you need to implement equals() method in the respective Class. This is useful when you put objects in a Set or a Map implementation where you want to identify the unique object, as these classes rely on equals() method to uniquely identify an object.

    By default the equals() implementation in Object class uses == operator to compare two objects which is comparing by references.

    Suppose you have a Class Color and it has one attribute String color. Now you have two instances of Color Class which both have color as blue. So these two instances are meaningfully equal, but to compare you need to implement equals method in Color class.

    Below example shows how to implement equals() method.

    It is good practice to do instanceof check as shown below, else you may get ClassCastException while casting the object.

    The equals() method follows below:

    • Reflexive: If a reference x is not null, then x.equals(x) must return true.
    • Symmetric: If references x,y are not null, then x.equals(y) should return true if and only if y.equals(x) returns true.
    • Transitive: If references x,y,z are not null, and if x.equals(y) & y.equals(z) return true then x.equals(z) must return true.
    • Consistent: If references x,y are not null, then multiple invocations of x.equals(y) must return true consistently or false consistently.
    • If a reference x is not null, then x.equals(null) must return false.


    public class Color {
        private String color;
        public Color(String color) {
            this.color = color;
        } 
    
        public String getColor() {
            return this.color;
        }    
    
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Color) {
                Color other = (Color) obj;
                if (other.color.equals(this.color)) {
                    return true;
                }
            } 
            return false;
        }
    
        public static void main(String args[]) {
            Color c1 = new Color("blue");
            Color c2 = new Color("blue");
            System.out.println(c1.equals(c2)); // prints true
        }
        
    }   

    2) Implementing hashCode() method

    When you use data structure like HashMap, apart from implementing equals() method, you also need to implement hashCode() to properly distribute the keys in HashMap.

    HashMap uses buckets to store keys, and to uniformly distribute keys across buckets, it uses hashCode() to decide in which bucket key will land up.

    A bucket may contain more then one key with same hashCode value but equals() method will determine which is the correct key. So if two objects are equal, they should always have same hashcode but the reverse is not mandatory.

    Below example shows how to implement equals() and hashCode() methods. Here we create a MobileNumber class and to determine if two mobile numbers are equal, we use prefix and the mobileNumber attributes.

    Note that in hashCode() implementation, we multiply intermediate values by a prime number so that its evenly generated.

    // Overrides equals and hashcode in Java    
    public final class MobileNumber {
        private final int prefix;
        private final int mobileNumber;
    	
        public MobileNumber(int prefix, int mobileNumber) {
            this.prefix = prefix;
            this.mobileNumber = mobileNumber;
        }
    	
        // equals method implementation
        @Override
        public boolean equals(Object o) {
            if (o == this) {
                return true;
            }
    
            if ( !(o instanceof MobileNumber) ) { // checks for null also
                return false;
            }
    
            MobileNumber mn = (MobileNumber) o;
            return (mn.mobileNumber == mobileNumber && mn.prefix == prefix);
        }
        
        // hashCode method implementation	
        @Override
        public int hashCode() {
            int result = 17;
            result = 31 * result + prefix;
            result = 31 * result + mobileNumber;
            return result;
        }
    	
        // Test
        public static void main(String[] args) {
        	MobileNumber mobileNumber1 = new MobileNumber(91, 1234565789);
        	MobileNumber mobileNumber2 = new MobileNumber(92, 1234565789);
        	System.out.println(mobileNumber1.equals(mobileNumber2));
        	
        	MobileNumber mobileNumber3 = new MobileNumber(91, 1234565789);
        	System.out.println(mobileNumber1.equals(mobileNumber3));
        }	
    
    }
    	

    Output :

    false
    true		

    3) Implement equals() and hashcode() using Java 7 Objects equals() & hashcode().

    Java Objects class also provides equals() & hashcode() methods to simplify the implementation as shown below. It makes equals() & hashcode() implementations more compact.

    Objects equals() method will return true if both the arguments are equal while hashcode() will return a hashcode if argument is not null.

    import java.util.Objects;
    	
    public final class MobileNumber {
        private final int prefix;
        private final int mobileNumber;
            
        public MobileNumber(int prefix, int mobileNumber) {
            this.prefix = prefix;
            this.mobileNumber = mobileNumber;
        }
        
        // equals method implementation	
        @Override
        public boolean equals(Object o) {
            if (o == null) {
                return false;
            }
    
            if ( getClass() != o.getClass() ) {
                return false;
            }
            MobileNumber mn = (MobileNumber) o;
            return (Objects.equals(this.prefix, mn.prefix) 
                && Objects.equals(this.mobileNumber, mn.mobileNumber));
        }
         
        // hashCode method implementation		 
        @Override
        public int hashCode() {
            return Objects.hash(this.prefix, this.mobileNumber);
        }
    
        // Test
        public static void main(String[] args) {
        	MobileNumber mobileNumber1 = new MobileNumber(91, 1234565789);
        	MobileNumber mobileNumber2 = new MobileNumber(92, 1234565789);
        	System.out.println(mobileNumber1.equals(mobileNumber2));
        	
        	MobileNumber mobileNumber3 = new MobileNumber(91, 1234565789);
        	System.out.println(mobileNumber1.equals(mobileNumber3));
        }	
    
    }   

    Output :

    false
    true

    4) Using Apache Commons Lang EqualsBuilder and HashCodeBuilder method.

    You can also use Apache commons lang library to implement equals() and hashcode() methods. You can specify the Class attribute (you want to use in implementing equals and hashcode) in the EqualsBuilder or HashCodeBuilder append method.

    You need to download Apache Commons Lang library from here download commons-lang3-3.7.jar
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.7</version>
    </dependency>   

    import org.apache.commons.lang3.builder.EqualsBuilder;
    import org.apache.commons.lang3.builder.HashCodeBuilder;
    	
    public final class MobileNumber {
        private final int prefix;
        private final int mobileNumber;
            
        public MobileNumber(int prefix, int mobileNumber) {
            this.prefix = prefix;
            this.mobileNumber = mobileNumber;
        }
        
        // equals method implementation	              
        @Override
        public boolean equals(Object o) {
            if (o == null) {
                return false;
            }
    
            if ( getClass() != o.getClass() ) {
                return false;
            }
            MobileNumber mn = (MobileNumber) o;
        
            return new EqualsBuilder()
                .append(prefix, mn.prefix)
                .append(mobileNumber, mn.mobileNumber)
                .isEquals();
        }
        
        // hashCode method implementation		
        @Override
        public int hashCode() {
            return new HashCodeBuilder(17, 31)
            .append(this.prefix)
            .append(this.mobileNumber)
            .toHashCode();
        }
    	
        // Test
        public static void main(String[] args) {
        	MobileNumber mobileNumber1 = new MobileNumber(91, 1234565789);
        	MobileNumber mobileNumber2 = new MobileNumber(92, 1234565789);
        	System.out.println(mobileNumber1.equals(mobileNumber2));
        	
        	MobileNumber mobileNumber3 = new MobileNumber(91, 1234565789);
        	System.out.println(mobileNumber1.equals(mobileNumber3));
        }	
    }
       

    Output :

    false
    true	

    References :

    https://docs.oracle.com/javase/8/docs/api/java/util/Objects.html#equals-java.lang.Object-

    https://docs.oracle.com/javase/8/docs/api/java/util/Objects.html#hashCode-java.lang.Object-
    Comments

    Leave a Reply

    Your email address will not be published. Required fields are marked *











    Share This