Sunday, 29 November 2015

Difference Between == Operator and equals() method

equals() method is a non-static method of java.lang.Object class. As all classes in java are sub classes of Object class, this method is inherited to every class you create in java. Here is the method signature of equals() method.

public boolean equals(Object obj)

equals() method takes one argument “obj” of type Object class and returns true if object calling this method is same as “obj”. For example, if a1 and a2 are two reference variables of type class A and they are pointing to same object then invoking a1.equals(a2) will return true.

Below is the example to demonstrate the equals() method.

class A
{
    int i = 10;
}

public class Test
{
   public static void main(String[] args)
   {
       //Creating object of Class A and assigning it to a1

       A a1 = new A(); 

       //a1 is assigned to a2

       A a2 = a1;

       //That means a1 and a2 are pointing to same object.

       //Calling a1.equals(a2) will return true

       System.out.println(a1.equals(a2));       //Output : true

       //Creating another object of Class A and assigning it to a2

       a2 = new A();

       //Now, a1 and a2 will be pointing to different objects.

       //Now calling a1.equals(a2) will return false

       System.out.println(a1.equals(a2));      //Output : false
   }
}

Overriding equals() method in your class :

As equals() method is not a final method, you can override it in your class so that you can compare the contents of two objects not just their physical address. i.e you can override equals() method so that it should return true if two objects have same contents.

Below example shows how to override equals() method to compare the contents of two objects.

class A
{
    int i;

    public A(int i)
    {
        this.i = i;
    }

    //Overriding equals() method

    @Override
    public boolean equals(Object obj)
    {
        A a = (A) obj;

        //Comparing the fields of calling object and passed object

        return this.i == a.i;
    }
}

public class Test
{
   public static void main(String[] args)
   {
      //Creating object of Class A with i = 10

      A a1 = new A(10);

      //Creating object of Class A with i = 20

      A a2 = new A(20);

      //a1 and a2 have different contents

      //So calling a1.equals(a2) will return false

      System.out.println(a1.equals(a2));        //Output : false

      //Changing the value of a2.i to 10

      a2.i = 10;

      //Now, a1 and a2 have same contents

      //Now, calling a1.equals(a2) will return true

      System.out.println(a1.equals(a2));      //Output : true
   }
}

Difference Between “==” Operator and “equals() method” :

As both “==” operator and equals() method are used to compare two objects, here are some differences between them.

 “==” operator returns true if and only if two references variables are pointing to same object. That means it checks only physical address of the objects not their contents. Default version of equals() method also compares physical address of two objects, but you can override and modify it to compare the contents of two objects.
You can use “==” operator to compare derived types as well as primitive types. But, equals() method is used only to compare the derived types.

Some Extra Points About equals() method :

  • equals() method is reflexive. i.e for any non-null reference variable ‘a’,  a.equals(a) will return true.
  • equals() method is symmetric. i.e for any non-null reference variables ‘a’ and ‘b’, a.equals(b) will return true if and only if b.equals(a) returns true.
  • equals() method is transitive. i.e for any non-null reference variables ‘a’, ‘b’ and ‘c’, if a.equals(b) returns true and b.equals(c) returns true then a.equals(c) will also return true.
  • equals() method is consistent. i.e for any non-null reference variables ‘a’ and ‘b’, multiple invocations of a.equals(b) will return either consistently true or consistently false, provided information used in equals() method on objects is not changed.
  • In all wrapper classes and String class, equals() method is overrided to compare the two objects on contents. i.e if there are two Integer objects or two String objects or two Double objects with same value then comparing them through equals() method will return true.


public class Test
{
   public static void main(String[] args)
   {
      Integer I1 = new Integer(10);

      Integer I2 = new Integer(10);

      System.out.println(I1.equals(I2));       //Output : true

      Double D1 = new Double(25.6);

      Double D2 = new Double(25.6);

      System.out.println(D1.equals(D2));      //Output : true

      String s1 = new String("abc");

      String s2 = new String("abc");

      System.out.println(s1.equals(s2));     //Output : true
   }
}

Here is an example to show how to override equals() method to compare two objects having more than one fields.

class A
{
    int i;

    double j;

    String s;

    public A(int i, double j, String s)
    {
        this.i = i;
        this.j = j;
        this.s = s;
    }

    //Overriding equals() method

    @Override
    public boolean equals(Object obj)
    {
        A a = (A) obj;

        //Comparing the fields of calling object and passed object

        return this.i == a.i && this.j == a.j && this.s == a.s;
    }
}

public class Test
{
   public static void main(String[] args)
   {
      A a1 = new A(10, 25.6, "First_Object");

      A a2 = new A(20, 45.8, "Second_Object");

      System.out.println(a1.equals(a2));       //Output : false

      a2 = new A(10, 25.6, "First_Object");

      System.out.println(a1.equals(a2));     //Output : true
   }
}

Saturday, 14 November 2015

Contract Between equals() And hashCode() Methods In Java

equals() and hashCode() methods of Object class are used to check the identity of objects. It is recommended that if you override one method then you must override other also. There is a relation or contract between these two methods that must be maintained all the time. That contract can be defined like this,

“If two objects are equal according to equals() method then they must have same hashcode() value. But, reverse is not always true.”

To maintain this contract all the time, it is recommended that you override both the methods. If you override equals() method and you don’t override hashCode() method, then two equal objects according to equals() method will have different hashCode values. This breaks the above contract. Therefore, you have to override equals() and hashCode() methods together.

Below example shows how to override equals() and hashCode() methods together.

class Person
{
    String firstName;
    String lastName;
    int age;

    public Person(String firstName, String lastName, int age)
    {
        this.firstName = firstName;

        this.lastName = lastName;

        this.age = age;
    }

    //Overriding equals() method

    @Override
    public boolean equals(Object obj)
    {
        Person person = (Person) obj;

        return this.firstName == person.firstName && this.lastName == person.lastName && this.age == person.age;
    }

    //Overriding hashCode() method

    @Override
    public int hashCode()
    {
        int hashCode = 0;

        hashCode += firstName.hashCode();

        hashCode += lastName.hashCode();

        hashCode += Integer.toString(age).hashCode();

        return hashCode;
    }
}

public class HashCodeMethodDemo
{
   public static void main(String[] args)
   {
       //Creating two objects of Person with same content

       Person p1 = new Person("Robin", "Smith", 42);

       Person p2 = new Person("Robin", "Smith", 42);

       //Now, comparing p1 and p2 using equals() method

       //It will return true as both the objects have same content

       System.out.println(p1.equals(p2));       //Output : true

       //They will also have same hashcode value.

       System.out.println(p1.hashCode());      //Output : 159138795

       System.out.println(p2.hashCode());      //Output : 159138795
   }

}

Some Extra Points About hashCode() method :

  • Whenever hashCode() method is called on the same object more than once during an execution of Java application, it must return consistently same value, provided object is not modified.
  • The value returned by hashCode() method may or may not change from one execution to another execution of the same application.
  • For most of the time, hashCode() method returns distinct integer for distinct objects if it is not overrided.
  • If two objects are not equal according to equals() method, then it is not necessary that their hashcode must also be different. But, it is a good practice to return different integers for different objects if hashCode() method is overrided.
  • If hashCode() method is overrided in a class and you want to know the original hashcode of an object of that class, then use System.identityHashCode() method. It returns hashcode of an object as same as that of default hashCode() method irrespective of whether hashCode() method is overrided or not.
  • Hashcode of a null object is zero.