Thursday 24 April 2014

How to compare two arrays in Java?

Predict the output of following Java program.
class Test
{
    public static void main (String[] args)
    {
        int arr1[] = {1, 2, 3};
        int arr2[] = {1, 2, 3};
        if (arr1 == arr2) // Same as arr1.equals(arr2)
            System.out.println("Same");
        else
            System.out.println("Not same");
    }
}
Output:
Not Same
In Java, arrays are first class objects. In the above program, arr1 and arr2 are two references to two different objects. So when we compare arr1 and arr2, two reference variables are compared, therefore we get the output as “Not Same” (See this for more examples).
How to compare array contents?
A simple way is to run a loop and compare elements one by one. Java provides a direct methodArrays.equals() to compare two arrays. Actually, there is a list of equals() methods in Arrays class for different primitive types (int, char, ..etc) and one for Object type (which is base of all classes in Java).
// we need to import java.util.Arrays to use Arrays.equals().
import java.util.Arrays;
class Test
{
    public static void main (String[] args)
    {
        int arr1[] = {1, 2, 3};
        int arr2[] = {1, 2, 3};
        if (Arrays.equals(arr1, arr2))
            System.out.println("Same");
        else
            System.out.println("Not same");
    }
}
Output:
Same
How to Deep compare array contents?
As seen above, the Arrays.equals() works fine and compares arrays contents. Now the questions, what if the arrays contain arrays inside them or some other references which refer to different object but have same values. For example, see the following program.
import java.util.Arrays;
class Test
{
    public static void main (String[] args)
    {
        // inarr1 and inarr2 have same values
        int inarr1[] = {1, 2, 3};
        int inarr2[] = {1, 2, 3};  
        Object[] arr1 = {inarr1};  // arr1 contains only one element
        Object[] arr2 = {inarr2};  // arr2 also contains only one element
        if (Arrays.equals(arr1, arr2))
            System.out.println("Same");
        else
            System.out.println("Not same");
    }
}
Output:
Not Same
So Arrays.equals() is not able to do deep comparison. Java provides another method for this Arrays.deepEquals() which does deep comparison.
import java.util.Arrays;
class Test
{
    public static void main (String[] args)
    {
        int inarr1[] = {1, 2, 3};
        int inarr2[] = {1, 2, 3};
        Object[] arr1 = {inarr1};  // arr1 contains only one element
        Object[] arr2 = {inarr2};  // arr2 also contains only one element
        if (Arrays.deepEquals(arr1, arr2))
            System.out.println("Same");
        else
            System.out.println("Not same");
    }
}
Output:
Same
How does Arrays.deepEquals() work?
It compares two objects using any custom equals() methods they may have (if they have an equals() method implemented other than Object.equals()). If not, this method will then proceed to compare the objects field by field, recursively. As each field is encountered, it will attempt to use the derived equals() if it exists, otherwise it will continue to recurse further.
This method works on a cyclic Object graph like this: A->B->C->A. It has cycle detection so ANY two objects can be compared, and it will never enter into an endless loop (Source:https://code.google.com/p/deep-equals/).
Exercise: Predict the output of following program
import java.util.Arrays;
class Test
{
   public static void main (String[] args)
   {
      int inarr1[] = {1, 2, 3};
      int inarr2[] = {1, 2, 3};
      Object[] arr1 = {inarr1};  // arr1 contains only one element
      Object[] arr2 = {inarr2};  // arr2 also contains only one element
      Object[] outarr1 = {arr1}; // outarr1 contains only one element
      Object[] outarr2 = {arr2}; // outarr2 also contains only one element       
      if (Arrays.deepEquals(outarr1, outarr2))
          System.out.println("Same");
      else
          System.out.println("Not same");
    }
}

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...