Java Arrays.equals () devuelve falso para dos matrices dimensionales

Tenía curiosidad por saber: ¿por qué Arrays.equals (double [] [], double [] []) devuelve false? cuando de hecho las matrices tienen el mismo número de elementos y cada elemento es el mismo?

Por ejemplo, realicé la siguiente prueba.

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"); 

Devuelve falso e imprime “No igual”.

por otro lado, si tengo algo como esto:

 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"); 

devuelve verdadero e imprime “Igual”. ¿El método solo funciona con dimensiones individuales? si es así, ¿hay algo similar para las matrices multidimensionales en Java?

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

Devuelve true si las dos matrices especificadas son profundamente iguales entre sí.

Como una int[] es una instanceof Object , una int[][] es una instanceof Object[] .


En cuanto a por qué Arrays.equals no “funciona” para matrices de dos dimensiones, se puede explicar paso a paso de la siguiente manera:

Para matrices, equals se define en términos de identidad de objeto

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

Esto se debe a que las matrices heredan sus equals de su superclase común, Object .

A menudo, realmente queremos igualdad de valor para las matrices, por eso, java.util.Arrays proporciona el método de utilidad static equals(int[], int[]) .

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

Matriz de matrices en Java

  • Un int[] es una instanceof Object
  • Un int[][] es una instanceof Object[]
  • Un int[][] NO es una instanceof int[]

Java realmente no tiene matrices bidimensionales. Ni siquiera tiene arrays multidimensionales. Java tiene una matriz de matrices.

java.util.Arrays.equals es “superficial”

Ahora considere este fragmento:

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

Aquí están los hechos:

  • Cada argumento es un Object[]
    • El elemento en el índice 0 es un int[] { 1 }
    • El elemento en el índice 1 es un int[] { 2, 3 } .
  • Hay dos instancias Object[]
  • Hay cuatro instancias int[]

Debe quedar claro del punto anterior que esto invoca la Arrays.equals(Object[], Object[]) . De la API:

Devuelve true si las dos matrices de Objects especificadas son iguales entre sí. Las dos matrices se consideran equal si ambas matrices contienen el mismo número de elementos, y todos los pares correspondientes de elementos en las dos matrices son iguales. Dos objetos e1 y e2 se consideran iguales si (e1==null ? e2==null : e1.equals(e2)) .

Ahora debe quedar claro por qué el fragmento de arriba muestra "false" ; es porque los elementos de las matrices Object[] no son iguales en la definición anterior (dado que un int[] tiene sus equals definidos por la identidad del objeto).

java.util.Arrays.deepEquals es “profundo”

Por el contrario, esto es lo que hace Arrays.deepEquals(Object[], Object[]) :

Devuelve true si las dos matrices especificadas son profundamente iguales entre sí. A diferencia del método equals(Object[],Object[]) , este método es apropiado para usar con matrices anidadas de profundidad arbitraria.

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

En Arrays.toString y Arrays.deepToString

Vale la pena señalar la analogía entre estos dos métodos y lo que hemos discutido hasta ahora con respecto a las matrices anidadas.

 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]]" 

De nuevo, el razonamiento es similar: Arrays.toString(Object[]) trata a cada elemento como un Object , y simplemente llama a su método toString() . Las matrices heredan su toString() de su Object superclase común.

Si desea que java.util.Arrays considere matrices anidadas, debe usar deepToString , al igual que necesita usar deepEquals .

java en realidad no tiene matrices multidimensionales. En cambio, tiene solo una matriz dimensional y las matrices multi d serán matrices de estas matrices de 1d. String.equals () solo se puede realizar en las matrices básicas de bloque único y, por lo tanto, no funciona para las transferencias multidimensionales.