Vergleichen von Arrays in Java

1. Übersicht

In diesem Tutorial werden verschiedene Möglichkeiten zum Vergleichen von Arrays in Java vorgestellt . Wir werden konventionelle Methoden behandeln und einige Beispiele mit Lambda- Ausdrücken sehen .

2. Arrays vergleichen

Wir werden Arrays in Java vergleichen, und wie wir wissen, sind dies Objekte. Lassen Sie uns daher einige grundlegende Konzepte aktualisieren:

  • Objekte haben Referenzen und Werte
  • Zwei gleiche Referenzen sollten auf denselben Wert verweisen
  • Zwei verschiedene Werte sollten unterschiedliche Referenzen haben
  • Zwei gleiche Werte haben nicht unbedingt die gleichen Referenzen
  • Primitive Werte werden nur pro Wert verglichen
  • String-Literale werden nur pro Wert verglichen

2.1. Objektreferenzen vergleichen

Wenn wir zwei Referenzen haben, die auf dasselbe Array verweisen, sollten wir bei einem Vergleich mit dem Operator == immer ein wahres Ergebnis erhalten .

Schauen wir uns ein Beispiel an:

String[] planes1 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" }; String[] planes2 = planes1;

Zuerst haben wir ein Array von Ebenenmodellen erstellt, auf die von Ebenen1 verwiesen wird . Wir erstellen dann Ebenen2 , die auf Ebenen1 verweisen . Auf diese Weise erstellen wir zwei Verweise auf dasselbe Array im Speicher . Daher gibt der Ausdruck "Ebenen1 == Ebenen2" true zurück .

Für Arrays entspricht die Methode equals () dem Operator == . Also, planes1.equals (planes2) liefert wahr , weil beide Referenzen auf das gleiche Objekt beziehen. Generell array1.eqauls (array2) wird wieder wahr , wenn und nur wenn der Ausdruck array1 == array2" kehrt wahr .

Lassen Sie uns behaupten, ob die beiden Referenzen gleich sind:

assertThat(planes1).isSameAs(planes2);

Stellen wir nun sicher, dass die Werte, auf die von Ebenen1 verwiesen wird, tatsächlich mit denen übereinstimmen, auf die von Ebenen2 verwiesen wird . Daher können wir das von Ebenen2 referenzierte Array ändern und prüfen, ob sich die Änderungen auf das von Ebenen1 referenzierte Array auswirken :

planes2[0] = "747";

Um dies endlich zu sehen, machen wir unsere Aussagen:

assertThat(planes1).isSameAs(planes2); assertThat(planes2[0]).isEqualTo("747"); assertThat(planes1[0]).isEqualTo("747");

Mit diesem Unit-Test konnten wir zwei Arrays anhand der Referenz vergleichen.

Wir haben jedoch nur bewiesen, dass eine Referenz, die einmal dem Wert einer anderen zugewiesen wurde, auf denselben Wert verweist.

Wir werden jetzt zwei verschiedene Arrays mit denselben Werten erstellen:

String[] planes1 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" }; String[] planes2 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" };

Da es sich um verschiedene Objekte handelt, wissen wir mit Sicherheit, dass sie nicht gleich sind. Wir können sie daher vergleichen:

assertThat(planes1).isNotSameAs(planes2);

Zusammenfassend haben wir in diesem Fall zwei Arrays im Speicher, die dieselben String- Werte in genau derselben Reihenfolge enthalten. Die referenzierten Arrays unterscheiden sich jedoch nicht nur im Inhalt, sondern auch die Referenzen selbst.

2.2. Array-Längen vergleichen

Die Länge der Arrays kann unabhängig von ihren Elementtypen oder davon verglichen werden, ob ihre Werte ausgefüllt sind oder nicht .

Erstellen wir zwei Arrays:

final String[] planes1 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" }; final Integer[] quantities = new Integer[] { 10, 12, 34, 45, 12, 43, 5, 2 };

Dies sind zwei verschiedene Arrays mit unterschiedlichen Elementtypen. In diesem Datensatz registrieren wir als Beispiel, wie viele Flugzeuge jedes Modells im Lager gespeichert sind. Lassen Sie uns nun Unit-Tests durchführen:

assertThat(planes1).hasSize(8); assertThat(quantities).hasSize(8);

Damit haben wir bewiesen, dass beide Arrays acht Elemente haben und dass die Eigenschaft length die richtige Anzahl von Elementen für jedes Array zurückgibt.

2.3. Vergleichen von Arrays mit Arrays.equals

Bisher haben wir Arrays nur anhand ihrer Objektidentitäten verglichen. Auf der anderen Seite, zu überprüfen , ob zwei Arrays hinsichtlich ihrer Inhalte gleich sind, Java die liefert Arrays.equals statische Methode. Diese Methode durchläuft die Arrays pro Position parallel und wendet den Operator == für jedes Elementpaar an .

Erstellen wir zwei verschiedene Arrays mit denselben String- Literalen in genau derselben Reihenfolge:

String[] planes1 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" }; String[] planes2 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" };

Und jetzt wollen wir behaupten, dass sie gleich sind:

assertThat(Arrays.equals(planes1, planes2)).isTrue();

Wenn wir die Reihenfolge der Werte des zweiten Arrays ändern:

String[] planes1 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" }; String[] planes2 = new String[] { "B738", "A320", "A321", "A319", "B77W", "B737", "A333", "A332" }; 

Wir werden ein anderes Ergebnis erhalten:

assertThat(Arrays.equals(planes1, planes2)).isFalse();

2.4. Vergleichen von Arrays mit Arrays.deepEquals

Die Verwendung des Operators == ist einfach, wenn wir einfache Typen in Java verwenden . Dies können primitive Typen oder String- Literale sein. Ein Vergleich zwischen Arrays von Objekten kann komplizierter sein. Der Grund dafür wird in unserem Artikel Arrays.deepEquals ausführlich erläutert . Sehen wir uns ein Beispiel an.

Beginnen wir zunächst mit einer Flugzeugklasse :

public class Plane { private final String name; private final String model; // getters and setters }

Und implementieren wir die Methoden hashCode und equals :

@Override public boolean equals(Object o)  if (this == o) return true; if (o == null  @Override public int hashCode() { return Objects.hash(name, model); }

Zweitens erstellen wir die folgenden Arrays mit zwei Elementen:

Plane[][] planes1 = new Plane[][] { new Plane[]{new Plane("Plane 1", "A320")}, new Plane[]{new Plane("Plane 2", "B738") }}; Plane[][] planes2 = new Plane[][] { new Plane[]{new Plane("Plane 1", "A320")}, new Plane[]{new Plane("Plane 2", "B738") }}; 

Mal sehen, ob es sich um wahre, zutiefst gleiche Arrays handelt:

assertThat(Arrays.deepEquals(planes1, planes2)).isTrue();

Um sicherzustellen, dass unser Vergleich wie erwartet funktioniert, ändern wir jetzt die Reihenfolge unseres letzten Arrays:

Plane[][] planes1 = new Plane[][] { new Plane[]{new Plane("Plane 1", "A320")}, new Plane[]{new Plane("Plane 2", "B738") }}; Plane[][] planes2 = new Plane[][] { new Plane[]{new Plane("Plane 2", "B738")}, new Plane[]{new Plane("Plane 1", "A320") }};

Lassen Sie uns abschließend testen, ob sie tatsächlich nicht mehr gleich sind:

assertThat(Arrays.deepEquals(planes1, planes2)).isFalse();

2.5. Vergleichen von Arrays mit unterschiedlichen Ordnungen von Elementen

Um zu überprüfen, ob Arrays unabhängig von der Reihenfolge der Elemente gleich sind, müssen wir definieren, was eine Instanz unserer Ebene einzigartig macht . In unserem Fall reicht ein anderer Name oder ein anderes Modell aus, um festzustellen, dass sich eine Ebene von einer anderen unterscheidet. Wir haben dies festgestellt, indem wir bereits die Methoden hashCode und equals implementiert haben . Dies bedeutet, dass wir unsere Arrays sortieren müssen, bevor wir sie vergleichen können. Dafür brauchen wir einen Komparator :

Comparator planeComparator = (o1, o2) -> { if (o1.getName().equals(o2.getName())) { return o2.getModel().compareTo(o1.getModel()); } return o2.getName().compareTo(o1.getName()); };

In this Comparator, we're giving priority to the name. If the names are equal, we solve the ambiguity by looking at the model. We compare strings by using the compareTo method of type String.

We want to be able to find if arrays are equal regardless of the sorting order. To do that, let's now sort our arrays:

Arrays.sort(planes1[0], planeComparator); Arrays.sort(planes2[0], planeComparator);

And finally, let's test them:

assertThat(Arrays.deepEquals(planes1, planes2)).isTrue();

Having sorted the arrays in the same order first, we allow the deepEquals method to find if these two arrays are equal.

3. Conclusion

In diesem Tutorial haben wir verschiedene Möglichkeiten zum Vergleichen von Arrays gesehen. Zweitens haben wir den Unterschied zwischen dem Vergleich von Referenzen und Werten gesehen. Darüber hinaus haben wir untersucht, wie wir Arrays gründlich vergleichen können . Schließlich haben wir den Unterschied zwischen einem normalen Vergleich und einem tiefen Vergleich unter Verwendung von equals bzw. deepEquals gesehen .

Wie immer ist der vollständige Quellcode für die Beispiele auf GitHub verfügbar.