Java Arrays.equals() returnează false pentru array-uri bidimensionale (Programare, Java, Array-Uri)

Achilles a intrebat.

Eram doar curios să știu – de ce Arrays.equals(double[][], double[][]) returnează false? când de fapt array-urile au același număr de elemente și fiecare element este același?

De exemplu, am efectuat următorul 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");

Returnează false și tipărește „Not-equal”.

pe de altă parte, dacă am ceva de genul următor:

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

returnează adevărat și tipărește „Egal”. Metoda funcționează doar cu dimensiuni unice? dacă da, există ceva similar pentru array-uri multidimensionale în Java?

2 răspunsuri
polygenelubricanți

Utilizați deepEquals(Object[], Object[]).

Returnează true dacă cele două array-uri specificate sunt profund egale unul față de celălalt.

Deoarece un int[] este un instanceof Object, , an int[][] este un instanceof Object[].


În ceea ce privește de ce Arrays.equals nu „funcționează” pentru array-uri bidimensionale, poate fi explicat pas cu pas după cum urmează:

Pentru matrici, equals este definit în termeni de identitate a obiectului

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

Acest lucru se datorează faptului că array-urile își moștenesc equals de la superclasa lor comună, Object.

Desigur, deseori dorim cu adevărat egalitatea valorilor pentru array-uri, motiv pentru care java.util.Arrays oferă funcția static metoda utilitară equals(int[], int[]).

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

Array de array-uri în Java

  • Un int[] este un instanceof Object
  • An int[][] este un instanceof Object[]
  • An int[][] este NU an instanceof int[]

Java nu are cu adevărat array-uri bidimensionale. Nu are nici măcar array-uri multidimensionale. Java are array de array-uri.

java.util.Arrays.equals este „superficial”

Acum, luați în considerare acest fragment:

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

Iată faptele:

  • Fiecare argument este un Object[]
    • Elementul de la indexul 0 este un int[] { 1 }
    • Elementul de la indexul 1 este un int[] { 2, 3 }.
  • Există două Object[] instanțe
  • Există patru int[] instanțe

Ar trebui să fie clar din punctul anterior că acest lucru invocă Arrays.equals(Object[], Object[]) supraîncărcare. Din API:

Returnează true dacă cele două rețele specificate de Objects sunt egale între ele. Cele două matrici sunt considerate equal dacă ambele array-uri conțin același număr de elemente și dacă toate perechile de elemente corespunzătoare din cele două array-uri sunt egale. Două obiecte e1 și e2 sunt considerate egale dacă (e1==null ? e2==null : e1.equals(e2)).

Acum ar trebui să fie clar de ce se tipărește fragmentul de mai sus "false"; este pentru că elementele din Object[] nu sunt egale conform definiției de mai sus (deoarece un element de matrice int[] are propriul equals definită de identitatea obiectului).

java.util.Arrays.deepEquals este „deep”

În contrast, iată ce se întâmplă cu Arrays.deepEquals(Object[], Object[]) face:

Returnează true dacă cele două matrici specificate sunt profund egale unul cu celălalt. Spre deosebire de metoda equals(Object[],Object[]) această metodă este adecvată pentru a fi utilizată cu array-uri imbricate de adâncime arbitrară.

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

Pe Arrays.toString și Arrays.deepToString

Merită să remarcăm analogia dintre aceste două metode și ceea ce am discutat până acum cu privire la array-urile imbricate.

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

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

Din nou, raționamentul este similar: Arrays.toString(Object[]) tratează fiecare element ca pe un Object, , și se apelează doar toString() metoda . Array-urile moștenesc toString() de la superclasa lor comună Object.

Dacă doriți ca java.util.Arrays să luați în considerare array-uri imbricate, trebuie să utilizați deepToString, , la fel cum trebuie să folosiți deepEquals.

Comentarii

  • Foarte bine explicat… Am încercat să dau click mai devreme, dar mi s-a cerut să aștept 10 minute :)… Tocmai am făcut-o. –  > Por Achilles.
  • @Achilles: Încerc să fac tot ce pot. Mă bucur să vă ajut. –  > Por polygenelubricants.
  • Într-adevăr: explicație solidă! +1 –  > Por Bart Kiers.
  • De asemenea, deepHashCode() docs.oracle.com/javase/6/docs/api/java/java/util/… care este utilă pentru a crea „obiecte de valoare” în cazul în care doriți să implementați atât „equals()”, cât și „hashCode()”. –  > Por J.Churchill.
  • Explicat ca un profesionist! Mulțumesc pentru explicația solidă –  > Por KNIGHT MAHAJAN.
utilizator2209812

java nu are de fapt array-uri multidimensionale. În schimb, are doar matrice unidimensională, iar matricele multidimensionale vor fi matrici ale acestei matrice 1d . String.equals() poate fi efectuat numai pentru array-urile de bază , cu un singur bloc și, prin urmare, nu funcționează pentru array-urile multidimensionale.