Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Arrays.equals() returns false for two dimensional arrays

Tags:

java

arrays

I was just curious to know - why does Arrays.equals(double[][], double[][]) return false? when in fact the arrays have the same number of elements and each element is the same?

For example I performed the following test.

double[][] a,  b; int size =5;  a=new double[size][size]; b=new double[size][size];  for( int i = 0; i < size; i++ )     for( int j = 0; j < size; j++ ) {         a[i][j]=1.0;         b[i][j]=1.0;     }  if(Arrays.equals(a, b))     System.out.println("Equal"); else     System.out.println("Not-equal"); 

Returns false and prints "Not-equal".

on the other hand, if I have something like this:

double[] a,  b; int size =5;  a=new double[size]; b=new double[size];  for( int i = 0; i < size; i++ ){     a[i]=1.0;     b[i]=1.0; }   if(Arrays.equals(a, b))     System.out.println("Equal"); else     System.out.println("Not-equal"); 

returns true and prints "Equal". Does the method only work with single dimensions? if so, is there something similar for multi-dimensional arrays in Java?

like image 946
Faheem Avatar asked Apr 27 '10 12:04

Faheem


People also ask

Do 2D array arrays equal work?

equals() can be only performed to the basic , single block arrays and hence it doesn't work for multidimensional arrrays.

Can you check if two arrays are equal Java?

The Arrays. equals() method checks the equality of the two arrays in terms of size, data, and order of elements. This method will accept the two arrays which need to be compared, and it returns the boolean result true if both the arrays are equal and false if the arrays are not equal.

What are two-dimensional arrays in Java?

In Java, 2D arrays are stored as arrays of arrays. Therefore, the way 2D arrays are declared is similar 1D array objects. 2D arrays are declared by defining a data type followed by two sets of square brackets.

Does arrays copyOf work for 2D arrays?

copyOf() does not deep copy a 2d matrix. It just refers same 2nd dimension arrays.

How to check if two arrays are equal in Java?

In other words, two arrays are equal if they contain the same elements in the same order. Also, two array references are considered equal if both are null. Arrays class in java provide the method Arrays.equals () to check whether two arrays are equal or not.

Why doesn't the equals () method work for two dimensional arrays?

As to why Arrays.equals doesn't "work" for two dimensional arrays, it can be explained step by step as follows: This is because arrays inherit their equals from their common superclass, Object. Often we really want value equality for arrays, of course, which is why java.util.Arrays provides the static utility method equals (int [], int []).

Is there a two dimensional array in Java?

Java doesn't really have two dimensional arrays. It doesn't even really have multidimensional arrays. Java has array of arrays. The element at index 1 is an int [] { 2, 3 }. It should be clear from the previous point that this invokes Arrays.equals (Object [], Object []) overload. From the API:

What happens if the length of the arrays are not equal?

If the arrays are equal then the value of the result variable will remain true. And also if the length of the arrays is not equal it will return false. Example 1: Below is the implementation of the above approach.


1 Answers

Use deepEquals(Object[], Object[]).

Returns true if the two specified arrays are deeply equal to one another.

Since an int[] is an instanceof Object, an int[][] is an instanceof Object[].


As to why Arrays.equals doesn't "work" for two dimensional arrays, it can be explained step by step as follows:

For arrays, equals is defined in terms of object identity

System.out.println(     (new int[] {1,2}).equals(new int[] {1,2}) ); // prints "false" 

This is because arrays inherit their equals from their common superclass, Object.

Often we really want value equality for arrays, of course, which is why java.util.Arrays provides the static utility method equals(int[], int[]).

System.out.println(     java.util.Arrays.equals(         new int[] {1,2},         new int[] {1,2}     ) ); // prints "true" 

Array of arrays in Java

  • An int[] is an instanceof Object
  • An int[][] is an instanceof Object[]
  • An int[][] is NOT an instanceof int[]

Java doesn't really have two dimensional arrays. It doesn't even really have multidimensional arrays. Java has array of arrays.

java.util.Arrays.equals is "shallow"

Now consider this snippet:

System.out.println(     java.util.Arrays.equals(         new int[][] {             { 1 },             { 2, 3 },         },         new int[][] {             { 1 },             { 2, 3 },         }     ) ); // prints "false" 

Here are the facts:

  • Each argument is an Object[]
    • The element at index 0 is an int[] { 1 }
    • The element at index 1 is an int[] { 2, 3 }.
  • There are two Object[] instances
  • There are four int[] instances

It should be clear from the previous point that this invokes Arrays.equals(Object[], Object[]) overload. From the API:

Returns true if the two specified arrays of Objects are equal to one another. The two arrays are considered equal if both arrays contain the same number of elements, and all corresponding pairs of elements in the two arrays are equal. Two objects e1 and e2 are considered equal if (e1==null ? e2==null : e1.equals(e2)).

Now it should be clear why the above snippet prints "false"; it's because the elements of the Object[] arrays are not equal by the above definition (since an int[] has its equals defined by object identity).

java.util.Arrays.deepEquals is "deep"

In contrast, here's what Arrays.deepEquals(Object[], Object[]) does:

Returns true if the two specified arrays are deeply equal to one another. Unlike the equals(Object[],Object[]) method, this method is appropriate for use with nested arrays of arbitrary depth.

System.out.println(     java.util.Arrays.deepEquals(         new int[][] {             { 1 },             { 2, 3 },         },         new int[][] {             { 1 },             { 2, 3 },         }     ) ); // prints "true" 

On Arrays.toString and Arrays.deepToString

It's worth noting the analogy between these two methods and what we've discussed so far with regards to nested arrays.

System.out.println(     java.util.Arrays.toString(         new int[][] {             { 1 },             { 2, 3 },         }     ) ); // prints "[[I@187aeca, [I@e48e1b]"  System.out.println(     java.util.Arrays.deepToString(         new int[][] {             { 1 },             { 2, 3 },         }     ) ); // prints "[[1], [2, 3]]" 

Again, the reasoning is similar: Arrays.toString(Object[]) treats each element as an Object, and just call its toString() method. Arrays inherit its toString() from their common superclass Object.

If you want java.util.Arrays to consider nested arrays, you need to use deepToString, just like you need to use deepEquals.

like image 154
polygenelubricants Avatar answered Sep 28 '22 07:09

polygenelubricants