Arrays.deepEquals

1. Übersicht

In diesem Tutorial werden wir uns mit den Details der deepEquals- Methode aus der Arrays- Klasse befassen . Wir werden sehen, wann wir diese Methode anwenden sollten, und wir werden einige einfache Beispiele durchgehen.

Weitere Informationen zu den verschiedenen Methoden in der Klasse java.util.Arrays finden Sie in unserer Kurzanleitung.

2. Zweck

Wir sollten die deepEquals- Methode verwenden, wenn wir die Gleichheit zwischen zwei verschachtelten oder mehrdimensionalen Arrays überprüfen möchten . Wenn wir zwei Arrays aus benutzerdefinierten Objekten vergleichen möchten, wie wir später sehen werden, müssen wir die Methode equals überschreiben .

Lassen Sie uns nun weitere Details zur deepEquals- Methode herausfinden .

2.1. Syntax

Wir beginnen mit einem Blick auf die Methodensignatur :

public static boolean deepEquals(Object[] a1, Object[] a2)

Anhand der Methodensignatur stellen wir fest, dass wir deepEquals nicht verwenden können , um zwei eindimensionale Arrays primitiver Datentypen zu vergleichen . Dazu müssen wir entweder das primitive Array in den entsprechenden Wrapper einbinden oder die Methode Arrays.equals verwenden, die Methoden für primitive Arrays überladen hat.

2.2. Implementierung

Durch die Analyse der internen Implementierung der Methode können wir feststellen, dass die Methode nicht nur die Elemente der obersten Ebene der Arrays überprüft, sondern auch jedes Unterelement davon rekursiv überprüft .

Daher sollten wir vermeiden, die deepEquals- Methode mit Arrays zu verwenden, die eine Selbstreferenz haben, da dies zu einem java.lang.StackOverflowError führt .

Als nächstes wollen wir herausfinden, welche Ausgabe wir mit dieser Methode erhalten können.

3. Ausgabe

Die Arrays.deepEquals- Methode gibt Folgendes zurück:

  • true, wenn beide Parameter dasselbe Objekt sind (dieselbe Referenz haben)
  • true, wenn beide Parameter null sind
  • false, wenn nur einer der beiden Parameter null ist
  • false, wenn die Arrays unterschiedliche Längen haben
  • true, wenn beide Arrays leer sind
  • true, wenn die Arrays die gleiche Anzahl von Elementen enthalten und jedes Paar von Unterelementen zutiefst gleich ist
  • in anderen Fällen falsch

Im nächsten Abschnitt werden einige Codebeispiele vorgestellt.

4. Beispiele

Jetzt ist es an der Zeit, die deepEquals- Methode in Aktion zu betrachten. Außerdem vergleichen wir die deepEquals- Methode mit der equals- Methode aus derselben Arrays- Klasse.

4.1. Eindimensionale Arrays

Beginnen wir zunächst mit einem einfachen Beispiel und vergleichen zwei eindimensionale Arrays vom Typ Object :

 Object[] anArray = new Object[] { "string1", "string2", "string3" }; Object[] anotherArray = new Object[] { "string1", "string2", "string3" }; assertTrue(Arrays.equals(anArray, anotherArray)); assertTrue(Arrays.deepEquals(anArray, anotherArray));

Wir sehen, dass sowohl die equals- als auch die deepEquals- Methode true zurückgeben . Lassen Sie uns herausfinden, was passiert, wenn ein Element unserer Arrays null ist :

 Object[] anArray = new Object[] { "string1", null, "string3" }; Object[] anotherArray = new Object[] { "string1", null, "string3" }; assertTrue(Arrays.equals(anArray, anotherArray)); assertTrue(Arrays.deepEquals(anArray, anotherArray));

Wir sehen, dass beide Behauptungen vergehen. Wir können daher den Schluss ziehen, dass bei Verwendung der deepEquals- Methode Nullwerte in jeder Tiefe der Eingabearrays akzeptiert werden .

Aber versuchen wir noch etwas und überprüfen wir das Verhalten mit verschachtelten Arrays:

 Object[] anArray = new Object[] { "string1", null, new String[] {"nestedString1", "nestedString2" }}; Object[] anotherArray = new Object[] { "string1", null, new String[] {"nestedString1", "nestedString2" } }; assertFalse(Arrays.equals(anArray, anotherArray)); assertTrue(Arrays.deepEquals(anArray, anotherArray));

Hier finden wir heraus, dass deepEquals true zurückgibt , während equals false zurückgibt . Dies liegt daran, dass deepEquals sich bei der Begegnung mit einem Array rekursiv aufruft , während equals nur die Referenzen der Sub-Arrays vergleicht.

4.2. Mehrdimensionale Arrays primitiver Typen

Als nächstes überprüfen wir das Verhalten mit mehrdimensionalen Arrays. Im nächsten Beispiel haben die beiden Methoden unterschiedliche Ausgaben, was die Tatsache unterstreicht, dass wir beim Vergleich mehrdimensionaler Arrays deepEquals anstelle der Methode equals verwenden sollten:

 int[][] anArray = { { 1, 2, 3 }, { 4, 5, 6, 9 }, { 7 } }; int[][] anotherArray = { { 1, 2, 3 }, { 4, 5, 6, 9 }, { 7 } }; assertFalse(Arrays.equals(anArray, anotherArray)); assertTrue(Arrays.deepEquals(anArray, anotherArray));

4.3. Mehrdimensionale Arrays von benutzerdefinierten Objekten

Lassen Sie uns abschließend das Verhalten von deepEquals- und equals- Methoden überprüfen , wenn Sie die Gleichheit zweier mehrdimensionaler Arrays für ein benutzerdefiniertes Objekt testen:

Beginnen wir mit der Erstellung einer einfachen Personenklasse :

 class Person { private int id; private String name; private int age; // constructor & getters & setters @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof Person)) return false; Person person = (Person) obj; return id == person.id && name.equals(person.name) && age == person.age; } }

Es ist notwendig, die Methode equals für unsere Person- Klasse zu überschreiben . Andernfalls vergleicht die Standardmethode equals nur die Referenzen der Objekte.

Berücksichtigen wir auch , dass wir , obwohl dies für unser Beispiel nicht relevant ist, hashCode immer überschreiben sollten, wenn wir die Methode equals überschreiben , damit wir nicht gegen ihre Verträge verstoßen.

Als nächstes können wir zwei mehrdimensionale Arrays der Person- Klasse vergleichen:

 Person personArray1[][] = { { new Person(1, "John", 22), new Person(2, "Mike", 23) }, { new Person(3, "Steve", 27), new Person(4, "Gary", 28) } }; Person personArray2[][] = { { new Person(1, "John", 22), new Person(2, "Mike", 23) }, { new Person(3, "Steve", 27), new Person(4, "Gary", 28) } }; assertFalse(Arrays.equals(personArray1, personArray2)); assertTrue(Arrays.deepEquals(personArray1, personArray2));

Durch den rekursiven Vergleich der Unterelemente haben die beiden Methoden wiederum unterschiedliche Ergebnisse.

Schließlich ist zu erwähnen, dass die Objects.deepEquals- Methode die Arrays.deepEquals- Methode intern ausführt, wenn sie mit zwei Object- Arrays aufgerufen wird :

 assertTrue(Objects.deepEquals(personArray1, personArray2));

5. Schlussfolgerung

In diesem kurzen Tutorial haben wir gelernt, dass wir die Arrays.deepEquals- Methode verwenden sollten, wenn wir die Gleichheit zwischen zwei verschachtelten oder mehrdimensionalen Arrays von Objekten oder primitiven Typen vergleichen möchten .

Wie immer ist der vollständige Quellcode des Artikels auf GitHub verfügbar.