Einführung
In diesem Lab werden Sie lernen, wie Sie in Java prüfen können, ob zwei Objekte gleich sind. Wir werden den grundlegenden Unterschied zwischen der Verwendung des ==-Operators und der equals()-Methode für den Vergleich von Objekten untersuchen.
Sie beginnen damit, die integrierte equals()-Methode zur Vergleich von Objekten zu verwenden und ihr Verhalten bei verschiedenen Datentypen zu verstehen. Dann werden Sie lernen, wie Sie die equals()-Methode in Ihren eigenen benutzerdefinierten Klassen überschreiben, um zu definieren, was für Ihre Objekte logische Gleichheit bedeutet. Abschließend werden Sie die wichtige Überlegung behandeln, wie Sie Null-Objekte bei der Durchführung von Gleichheitsüberprüfungen behandeln, um potenzielle NullPointerException-Fehler zu vermeiden.
Verwenden Sie die equals()-Methode für Gleichheitsüberprüfung
In diesem Schritt werden wir untersuchen, wie man in Java Objekte mit der equals()-Methode vergleicht. Während der ==-Operator prüft, ob zwei Objekt-Referenzen auf dasselbe Objekt im Speicher verweisen, ist die equals()-Methode dafür konzipiert, zu prüfen, ob zwei Objekte logisch gleich sind, d. h., dass sie denselben Wert oder Zustand repräsentieren.
Beginnen wir damit, eine einfache Java-Datei zu erstellen, um dieses Konzept zu demonstrieren.
Öffnen Sie die WebIDE und stellen Sie sicher, dass Sie sich im Verzeichnis
~/projectbefinden. Sie können dies überprüfen, indem Sie auf die Terminal-Eingabezeile schauen oderpwdeingeben und Enter drücken.Erstellen Sie eine neue Datei namens
EqualityDemo.javaim Verzeichnis~/project. Sie können dies tun, indem Sie mit der rechten Maustaste im Dateiexplorer links klicken und "Neue Datei" auswählen, dannEqualityDemo.javaeingeben.Öffnen Sie die Datei
EqualityDemo.javaim Editor und fügen Sie den folgenden Code ein:public class EqualityDemo { public static void main(String[] args) { String str1 = new String("hello"); String str2 = new String("hello"); String str3 = str1; System.out.println("Comparing String objects:"); System.out.println("str1 == str2: " + (str1 == str2)); System.out.println("str1.equals(str2): " + str1.equals(str2)); System.out.println("str1 == str3: " + (str1 == str3)); System.out.println("str1.equals(str3): " + str1.equals(str3)); System.out.println("\nComparing primitive types (int):"); int num1 = 10; int num2 = 10; System.out.println("num1 == num2: " + (num1 == num2)); } }In diesem Code:
- Wir erstellen zwei
String-Objekte,str1undstr2, mit demselben Inhalt ("hello"), aber unter Verwendung vonnew String(), was unterschiedliche Objekte im Speicher erstellt. - Wir erstellen eine dritte
String-Referenz,str3, und lassen sie auf dasselbe Objekt wiestr1verweisen. - Wir verwenden sowohl
==als auchequals()zum Vergleich vonstr1undstr2sowie vonstr1undstr3. - Wir zeigen auch einen Vergleich von primitiven
int-Typen mit==. Denken Sie daran, dassequals()für Objekte und nicht für primitive Typen verwendet wird.
- Wir erstellen zwei
Speichern Sie die Datei
EqualityDemo.java(Strg+S oder Cmd+S).Öffnen Sie das Terminal unten in der WebIDE.
Kompilieren Sie das Java-Programm, indem Sie den folgenden Befehl eingeben und Enter drücken:
javac EqualityDemo.javaWenn keine Fehler auftreten, sollten Sie keine Ausgabe sehen.
Führen Sie das kompilierte Programm aus, indem Sie den folgenden Befehl eingeben und Enter drücken:
java EqualityDemoSie sollten eine Ausgabe ähnlich der folgenden sehen:
Comparing String objects: str1 == str2: false str1.equals(str2): true str1 == str3: true str1.equals(str3): true Comparing primitive types (int): num1 == num2: trueBeachten Sie, dass
str1 == str2falseist, weil es sich um unterschiedliche Objekte im Speicher handelt, auch wenn sie denselben Inhalt haben. Allerdings iststr1.equals(str2)true, weil dieequals()-Methode derString-Klasse überschrieben wurde, um den tatsächlichen Inhalt der Strings zu vergleichen.str1 == str3isttrue, weilstr3auf dasselbe Objekt wiestr1verweist.
Dies zeigt den wesentlichen Unterschied zwischen == (Referenzgleichheit) und equals() (logische Gleichheit) beim Vergleich von Objekten in Java. Bei primitiven Typen wird == für den Wertvergleich verwendet.
Überschreiben Sie die equals()-Methode in einer benutzerdefinierten Klasse
Im vorherigen Schritt haben wir gesehen, wie die equals()-Methode für String-Objekte funktioniert. Die String-Klasse hat bereits die Standard-equals()-Methode (von der Object-Klasse geerbt) überschrieben, um einen sinnvollen Vergleich basierend auf dem Inhalt durchzuführen.
Wenn Sie jedoch Ihre eigenen benutzerdefinierten Klassen erstellen, verwendet die von Object geerbte Standard-equals()-Methode einfach den ==-Operator, was bedeutet, dass sie nur die Referenzgleichheit prüft. Um Objekte Ihrer benutzerdefinierten Klasse basierend auf ihren Attributen (logische Gleichheit) zu vergleichen, müssen Sie die equals()-Methode selbst überschreiben.
In diesem Schritt werden wir eine einfache Person-Klasse erstellen und ihre equals()-Methode überschreiben.
Stellen Sie sicher, dass Sie sich im Verzeichnis
~/projectin der WebIDE befinden.Erstellen Sie eine neue Datei namens
Person.javaim Verzeichnis~/project.Öffnen Sie
Person.javaund fügen Sie den folgenden Code für diePerson-Klasse ein:public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } // Default equals() method (inherited from Object) would only check reference equality // We need to override it to check for logical equality based on name and age @Override public boolean equals(Object obj) { // Step 1: Check if the objects are the same instance if (this == obj) { return true; } // Step 2: Check if the object is null or of a different class if (obj == null || getClass() != obj.getClass()) { return false; } // Step 3: Cast the object to the correct type Person person = (Person) obj; // Step 4: Compare the relevant attributes return age == person.age && name.equals(person.name); // Use equals() for String comparison } }In dieser
Person-Klasse:- Wir haben zwei private Attribute:
name(String) undage(int). - Wir haben einen Konstruktor, um diese Attribute zu initialisieren.
- Wir haben Getter-Methoden, um auf die Attribute zuzugreifen.
- Wir haben die
equals()-Methode überschrieben. Schauen wir uns die Schritte innerhalb der überschriebenenequals()-Methode an:if (this == obj): Dies ist eine Optimierung. Wenn die beiden Referenzen auf dasselbe Objekt verweisen, sind sie definitiv gleich.if (obj == null || getClass() != obj.getClass()): Dies prüft, ob das zu vergleichende Objekt null ist oder ob es keine Instanz derPerson-Klasse ist. Wenn einer der beiden Fälle zutrifft, können sie nicht gleich sein.Person person = (Person) obj;: Wir casten das generischeObjectin einPerson-Objekt, damit wir auf seinename- undage-Attribute zugreifen können.return age == person.age && name.equals(person.name);: Dies ist der Kern des logischen Vergleichs. Wir prüfen, ob dasage-Attribut gleich ist (unter Verwendung von==für primitive int-Werte) und ob dasname-Attribut gleich ist (unter Verwendung vonequals()fürString-Objekte).
- Wir haben zwei private Attribute:
Speichern Sie die Datei
Person.java.Jetzt erstellen wir eine weitere Datei,
PersonEqualityDemo.java, um unsere überschriebeneequals()-Methode zu testen. Erstellen Sie diese Datei im Verzeichnis~/project.Öffnen Sie
PersonEqualityDemo.javaund fügen Sie den folgenden Code ein:public class PersonEqualityDemo { public static void main(String[] args) { Person person1 = new Person("Alice", 30); Person person2 = new Person("Alice", 30); Person person3 = new Person("Bob", 25); Person person4 = person1; System.out.println("Comparing Person objects:"); System.out.println("person1 == person2: " + (person1 == person2)); System.out.println("person1.equals(person2): " + person1.equals(person2)); System.out.println("person1 == person3: " + (person1 == person3)); System.out.println("person1.equals(person3): " + person1.equals(person3)); System.out.println("person1 == person4: " + (person1 == person4)); System.out.println("person1.equals(person4): " + person1.equals(person4)); } }In dieser Demo-Klasse erstellen wir mehrere
Person-Objekte und vergleichen sie sowohl mit==als auch mit unserer überschriebenenequals()-Methode.Speichern Sie die Datei
PersonEqualityDemo.java.Öffnen Sie das Terminal. Stellen Sie sicher, dass Sie sich in
~/projectbefinden.Kompilieren Sie beide Java-Dateien. Sie können mehrere Dateien auf einmal kompilieren:
javac Person.java PersonEqualityDemo.javaDies sollte die Dateien
Person.classundPersonEqualityDemo.classerstellen.Führen Sie das Demo-Programm aus:
java PersonEqualityDemoSie sollten eine Ausgabe ähnlich der folgenden sehen:
Comparing Person objects: person1 == person2: false person1.equals(person2): true person1 == person3: false person1.equals(person3): false person1 == person4: true person1.equals(person4): trueWie erwartet ist
person1 == person2false, weil es sich um unterschiedliche Objekte handelt, aberperson1.equals(person2)isttrue, weil ihrnameund ihragelaut unserer überschriebenen Methode gleich sind.person1undperson3sind bei beiden Vergleichen nicht gleich.person1undperson4sind bei beiden Vergleichen gleich, weil sie auf dasselbe Objekt verweisen.
Durch das Überschreiben der equals()-Methode definieren Sie, was "gleich" für Objekte Ihrer benutzerdefinierten Klasse bedeutet, basierend auf ihrem logischen Zustand und nicht nur auf ihrer Speicheradresse.
Behandeln von Null-Objekten bei der Gleichheitsüberprüfung
Im vorherigen Schritt haben wir erfolgreich die equals()-Methode in unserer Person-Klasse überschrieben, um Objekte basierend auf ihren Attributen zu vergleichen. Ein entscheidender Aspekt beim Schreiben robuster equals()-Methoden ist der Umgang mit potenziellen null-Werten. Wenn Sie versuchen, eine Methode auf einem null-Objekt aufzurufen, führt dies zu einer NullPointerException, einem häufigen Fehler in Java.
Unsere überschriebene equals()-Methode in Person.java enthält bereits eine Prüfung auf null: if (obj == null || getClass() != obj.getClass()). Dies ist die Standardmethode, um den Fall zu behandeln, dass das zu vergleichende Objekt null ist.
In diesem Schritt werden wir demonstrieren, was passiert, wenn man ein Objekt mit null vergleicht, und bestätigen, dass unsere equals()-Methode diesen Fall korrekt behandelt.
Stellen Sie sicher, dass Sie sich im Verzeichnis
~/projectin der WebIDE befinden.Öffnen Sie die Datei
PersonEqualityDemo.java, die Sie im vorherigen Schritt erstellt haben.Fügen Sie die folgenden Zeilen in die
main-Methode nach den bestehenden Vergleichs-Anweisungen ein:System.out.println("\nComparing with null:"); System.out.println("person1.equals(null): " + person1.equals(null));Dieser Code fügt einfach einen Vergleich von
person1mitnullhinzu.Speichern Sie die Datei
PersonEqualityDemo.java.Öffnen Sie das Terminal. Stellen Sie sicher, dass Sie sich in
~/projectbefinden.Kompilieren Sie die geänderte Datei
PersonEqualityDemo.java:javac PersonEqualityDemo.javaDenken Sie daran, dass Sie nur die Dateien neu kompilieren müssen, die Sie geändert haben. Da
Person.javain diesem Schritt nicht geändert wurde, müssen wir nurPersonEqualityDemo.javakompilieren.Führen Sie das kompilierte Programm aus:
java PersonEqualityDemoSie sollten jetzt die vorherige Ausgabe gefolgt von dem neuen Vergleich mit
nullsehen:Comparing Person objects: person1 == person2: false person1.equals(person2): true person1 == person3: false person1.equals(person3): false person1 == person4: true person1.equals(person4): true Comparing with null: person1.equals(null): falseDie Ausgabe
person1.equals(null): falsebestätigt, dass unsere überschriebeneequals()-Methode den Vergleich mitnullkorrekt behandelt undfalsezurückgibt, ohne eineNullPointerExceptionzu werfen. Dies liegt daran, dass die Zeileif (obj == null || getClass() != obj.getClass())in derequals()-Methode unsererPerson-Klasse aufnullprüft, bevor versucht wird, auf Attribute vonobjzuzugreifen.
Der Umgang mit null ist ein kritischer Teil beim Schreiben robuster Java-Code, insbesondere bei der Behandlung von Objektvergleichen. Fügen Sie immer eine null-Prüfung am Anfang Ihrer überschriebenen equals()-Methode ein.
Zusammenfassung
In diesem Lab haben wir gelernt, wie man in Java prüft, ob zwei Objekte gleich sind. Wir haben zunächst den Unterschied zwischen dem ==-Operator, der die Referenzgleichheit prüft, und der equals()-Methode, die die logische Gleichheit prüft, verstanden. Wir haben dies anhand von String-Objekten und primitiven Datentypen demonstriert und beobachtet, wie sich == für Objekte anders verhält als equals().
Anschließend haben wir untersucht, wie man die equals()-Methode in benutzerdefinierten Klassen überschreibt, um eigene Kriterien für die Objektgleichheit zu definieren. Dies ist entscheidend, um sicherzustellen, dass unsere benutzerdefinierten Objekte basierend auf ihrem Inhalt oder Zustand und nicht nur auf ihrer Speicheradresse verglichen werden. Schließlich haben wir gelernt, wie wichtig es ist, Null-Objekte innerhalb der equals()-Methode zu behandeln, um NullPointerException zu vermeiden und robuste Gleichheitsüberprüfungen sicherzustellen.



