Menu
Coddy logo textTech

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 denselben Speicherort zeigen. Um den tatsächlichen Inhalt von Objekten zu vergleichen, müssen Sie die equals()-Methode ü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 equals()-Methode folgt einem Standardmuster: Zuerst wird geprüft, ob es sich um dasselbe Objekt handelt, dann wird der Typ überprüft und schließlich werden die relevanten Felder verglichen.

Wann immer Sie equals() überschreiben, müssen Sie auch hashCode() überschreiben. Dies ist ein Vertrag in Java: Objekte, die gleich sind, müssen denselben Hash-Code haben. Hash-basierte Sammlungen wie HashMap und HashSet verlassen sich auf diese Regel, um korrekt zu funktionieren.

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

Die Hilfsmethode Objects.hash() generiert einen Hash-Code aus denselben Feldern, die in equals() verwendet werden. Wenn zwei Person-Objekte denselben name und dasselbe age haben, werden sie als gleich betrachtet und erzeugen identische Hash-Codes, was ein konsistentes Verhalten in Collections gewährleistet.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Studenten-Erfassungssystem erstellen, das die Objektgleichheit korrekt implementiert. Sie werden eine Student-Klasse erstellen, in der zwei Studenten als gleich gelten, wenn sie dieselbe Studenten-ID und denselben Namen haben – unabhängig davon, ob es sich um dasselbe Objekt im Speicher handelt.

Sie werden Ihren Code in zwei Dateien organisieren:

  • Student.java: Erstellen Sie eine Klasse, die einen Studenten mit drei privaten Feldern repräsentiert: studentId (String), name (String) und gpa (double). Fügen Sie einen Konstruktor zur Initialisierung aller Felder und Getter-Methoden für jedes Feld hinzu.

    Überschreiben Sie die equals()-Methode so, dass zwei Student-Objekte als gleich betrachtet werden, wenn sie dieselbe studentId UND denselben name haben. Folgen Sie dem Standardmuster: Prüfen Sie auf dieselbe Referenz, prüfen Sie auf null und den Typ, und vergleichen Sie dann die relevanten Felder.

    Überschreiben Sie die hashCode()-Methode unter Verwendung von Objects.hash() mit denselben Feldern, die in equals() verwendet werden. Denken Sie daran, java.util.Objects am Anfang Ihrer Datei zu importieren.

  • Main.java: Erwecken Sie Ihre Student-Klasse zum Leben, indem Sie Studenten-Objekte vergleichen. Sie erhalten sechs Eingaben, die zwei Studenten repräsentieren: die ID, den Namen und den GPA des ersten Studenten, gefolgt von der ID, dem Namen und dem GPA des zweiten Studenten.

    Erstellen Sie beide Student-Objekte, führen Sie dann drei Vergleiche durch und geben Sie die Ergebnisse aus:

    1. Geben Sie "Same reference: " aus, gefolgt davon, ob der erste Student sich selbst gleicht (sollte immer true sein)
    2. Geben Sie "Content equality: " aus, gefolgt davon, ob der erste Student dem zweiten Studenten gleicht (basierend auf Ihrer equals-Implementierung)
    3. Geben Sie "Hash codes match: " aus, gefolgt davon, ob beide Studenten denselben Hash-Code haben

Sie erhalten sechs Eingaben: ID des ersten Studenten (String), Name des ersten Studenten (String), GPA des ersten Studenten (double), ID des zweiten Studenten (String), Name des zweiten Studenten (String) und GPA des zweiten Studenten (double).

Beachten Sie, dass wenn zwei Studenten übereinstimmende IDs und Namen haben, sowohl equals() true zurückgibt ALS AUCH ihre Hash-Codes übereinstimmen – dies ist der Vertrag, den Sie einhalten müssen!

Spickzettel

Der ==-Operator prüft, ob zwei Referenzen auf denselben Speicherort zeigen, nicht ob Objekte denselben Inhalt haben.

Um den Objektinhalt zu vergleichen, überschreiben Sie die equals()-Methode nach diesem Muster:

@Override
public boolean equals(Object obj) {
    if (this == obj) return true;  // Dieselbe Referenz
    if (obj == null || getClass() != obj.getClass()) return false;  // Null oder anderer Typ
    Person person = (Person) obj;  // In den richtigen Typ umwandeln
    return age == person.age && name.equals(person.name);  // Felder vergleichen
}

Wann immer Sie equals() überschreiben, müssen Sie auch hashCode() überschreiben. Dies ist ein Java-Vertrag: Gleiche Objekte müssen denselben Hash-Code haben.

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

Verwenden Sie Objects.hash() mit denselben Feldern, die in equals() verwendet werden. Dies stellt sicher, dass Hash-basierte Sammlungen wie HashMap und HashSet korrekt funktionieren.

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 lesen
        String id1 = scanner.nextLine();
        String name1 = scanner.nextLine();
        double gpa1 = scanner.nextDouble();
        scanner.nextLine(); // Zeilenumbruch konsumieren
        
        // Daten des zweiten Studenten lesen
        String id2 = scanner.nextLine();
        String name2 = scanner.nextLine();
        double gpa2 = scanner.nextDouble();
        
        // TODO: Zwei Student-Objekte mit den Eingabedaten erstellen
        
        // TODO: "Same reference: " ausgeben, gefolgt davon, ob student1 sich selbst gleicht
        
        // TODO: "Content equality: " ausgeben, gefolgt davon, ob student1 student2 gleicht
        
        // TODO: "Hash codes match: " ausgeben, gefolgt davon, ob beide Studenten denselben Hash-Code 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