Menu
CoddyTech

equals() und hashCode()

Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 42 von 87.

Beim Vergleichen von Objekten in Java prüft der Operator ==, ob zwei Referenzen auf dieselbe Speicherstelle verweisen. Um den tatsächlichen Inhalt von Objekten zu vergleichen, musst du die Methode equals() überschreiben.

public class Person {
    private String name;
    private int age;
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && name.equals(person.name);
    }
}

Die Methode equals() folgt einem Standardmuster: Prüfe zuerst, ob es dasselbe Objekt ist, verifiziere dann den Typ und vergleiche schließlich die relevanten Felder.

Wenn du equals() überschreibst, musst du auch hashCode() überschreiben. Das ist eine Vertragspflicht in Java: Gleiche Objekte müssen denselben Hashcode haben. Hashbasierte Sammlungen wie HashMap und HashSet sind auf diese Regel angewiesen, um korrekt zu funktionieren.

@Override
public int hashCode() {
    return Objects.hash(name, age);
}

Die Hilfsmethode Objects.hash() erzeugt einen Hashcode aus denselben Feldern, die auch in equals() verwendet werden. Wenn zwei Person-Objekte denselben Namen und dasselbe Alter haben, gelten sie als gleich und erzeugen identische Hashcodes, wodurch ein konsistentes Verhalten in Collections gewährleistet wird.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Studentenverwaltungssystem, das die Objektgleichheit korrekt implementiert. Du erstellst eine Klasse Student, in der zwei Studierende als gleich gelten, wenn sie dieselbe Matrikelnummer und denselben Namen haben, unabhängig davon, ob sie dasselbe Objekt im Speicher sind.

Du organisierst deinen Code auf zwei Dateien:

  • Student.java: Erstelle eine Klasse, die einen Studierenden mit drei privaten Feldern darstellt: studentId (String), name (String) und gpa (double). Füge einen Konstruktor hinzu, der alle Felder initialisiert, sowie Getter-Methoden für jedes Feld.

    Überschreibe die Methode equals(), sodass zwei Student-Objekte als gleich gelten, wenn sie dieselbe studentId UND denselben name haben. Halte dich an das Standardmuster: Prüfe, ob es sich um dieselbe Referenz handelt, prüfe auf null und den Typ und vergleiche dann die relevanten Felder.

    Überschreibe die Methode hashCode() mit Objects.hash() und verwende dabei dieselben Felder wie in equals(). Denke daran, java.util.Objects am Anfang deiner Datei zu importieren.

  • Main.java: Erwecke deine Student-Klasse zum Leben, indem du Student-Objekte vergleichst. Du erhältst sechs Eingaben, die zwei Studierende darstellen: zuerst die ID, den Namen und den Notendurchschnitt des ersten Studierenden, gefolgt von der ID, dem Namen und dem Notendurchschnitt des zweiten Studierenden.

    Erstelle beide Student-Objekte, führe dann drei Vergleiche durch und gib die Ergebnisse aus:

    1. Gib Same reference: aus, gefolgt davon, ob der erste Studierende mit sich selbst gleich ist (sollte immer true sein)
    2. Gib Content equality: aus, gefolgt davon, ob der erste Studierende mit dem zweiten Studierenden gleich ist (basierend auf deiner equals-Implementierung)
    3. Gib Hash codes match: aus, gefolgt davon, ob beide Studierenden denselben Hash-Code haben

Du erhältst sechs Eingaben: die ID des ersten Studierenden (String), den Namen des ersten Studierenden (String), den Notendurchschnitt des ersten Studierenden (double), die ID des zweiten Studierenden (String), den Namen des zweiten Studierenden (String) und den Notendurchschnitt des zweiten Studierenden (double).

Beachte: Wenn zwei Studierende übereinstimmende IDs und Namen haben, gibt equals() true zurück UND ihre Hash-Codes stimmen überein. Diesen Vertrag musst du einhalten!

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Daten des ersten Studenten einlesen
        String id1 = scanner.nextLine();
        String name1 = scanner.nextLine();
        double gpa1 = scanner.nextDouble();
        scanner.nextLine(); // Zeilenumbruch einlesen
        
        // Daten des zweiten Studenten einlesen
        String id2 = scanner.nextLine();
        String name2 = scanner.nextLine();
        double gpa2 = scanner.nextDouble();
        
        // TODO: Zwei Student-Objekte aus den Eingabedaten erstellen
        
        // TODO: "Same reference: " ausgeben, gefolgt von der Angabe, ob student1 gleich sich selbst ist
        
        // TODO: "Content equality: " ausgeben, gefolgt von der Angabe, ob student1 gleich student2 ist
        
        // TODO: "Hash codes match: " ausgeben, gefolgt von der Angabe, ob beide Studenten denselben Hashcode haben
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Java-Compiler