Menu
Coddy logo textTech

equals() i hashCode()

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 42 z 87.

Podczas porównywania obiektów w Javie operator == sprawdza, czy dwa odwołania wskazują tę samą lokalizację w pamięci. Aby porównać rzeczywistą zawartość obiektów, musisz nadpisać metodę equals().

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);
    }
}

Metoda equals() opiera się na standardowym wzorcu: najpierw sprawdź, czy to ten sam obiekt, następnie zweryfikuj typ, a na końcu porównaj odpowiednie pola.

Za każdym razem, gdy przesłaniasz equals(), musisz również przesłonić hashCode(). To umowa w Java: obiekty, które są równe, muszą mieć ten sam kod skrótu. Kolekcje oparte na kodach skrótu, takie jak HashMap i HashSet, polegają na tej zasadzie, aby działać poprawnie.

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

Metoda narzędziowa Objects.hash() generuje kod skrótu z tych samych pól, które są używane w equals(). Jeśli dwa obiekty Person mają takie samo imię i wiek, zostaną uznane za równe i wygenerują identyczne kody skrótu, co zapewni spójne działanie w kolekcjach.

challenge icon

Wyzwanie

Łatwy

Stwórzmy system ewidencji studentów, który prawidłowo implementuje równość obiektów. Utworzysz klasę Student, w której dwóch studentów jest uznawanych za równych, jeśli mają ten sam identyfikator studenta i imię, niezależnie od tego, czy są tym samym obiektem w pamięci.

Rozmieścisz swój kod w dwóch plikach:

  • Student.java: Utwórz klasę reprezentującą studenta z trzema polami prywatnymi: studentId (String), name (String) i gpa (double). Dodaj konstruktor inicjalizujący wszystkie pola oraz metody pobierające dla każdego pola.

    Nadpisz metodę equals(), aby dwa obiekty Student były uznawane za równe, gdy mają ten sam studentId ORAZ tę samą wartość name. Zastosuj standardowy schemat: sprawdź, czy to ta sama referencja, sprawdź, czy obiekt nie jest null i czy ma odpowiedni typ, a następnie porównaj odpowiednie pola.

    Nadpisz metodę hashCode(), używając Objects.hash() z tymi samymi polami, które są używane w equals(). Pamiętaj, aby zaimportować java.util.Objects na początku pliku.

  • Main.java: Ożyw swoją klasę Student, porównując obiekty studentów. Otrzymasz sześć danych wejściowych reprezentujących dwóch studentów: najpierw identyfikator, imię i GPA pierwszego studenta, a następnie identyfikator, imię i GPA drugiego studenta.

    Utwórz oba obiekty Student, a następnie wykonaj trzy porównania i wypisz wyniki:

    1. Wypisz Same reference: , a następnie informację, czy pierwszy student jest równy samemu sobie (powinno to zawsze być true)
    2. Wypisz Content equality: , a następnie informację, czy pierwszy student jest równy drugiemu studentowi (na podstawie implementacji equals)
    3. Wypisz Hash codes match: , a następnie informację, czy obaj studenci mają ten sam kod skrótu

Otrzymasz sześć danych wejściowych: identyfikator pierwszego studenta (String), imię pierwszego studenta (String), GPA pierwszego studenta (double), identyfikator drugiego studenta (String), imię drugiego studenta (String) oraz GPA drugiego studenta (double).

Zauważ, że gdy dwóch studentów ma takie same identyfikatory i imiona, equals() zwraca true ORAZ ich kody skrótu są zgodne. To jest kontrakt, którego musisz przestrzegać!

Spróbuj swoich sił

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Wczytaj dane pierwszego studenta
        String id1 = scanner.nextLine();
        String name1 = scanner.nextLine();
        double gpa1 = scanner.nextDouble();
        scanner.nextLine(); // pomiń znak nowej linii
        
        // Wczytaj dane drugiego studenta
        String id2 = scanner.nextLine();
        String name2 = scanner.nextLine();
        double gpa2 = scanner.nextDouble();
        
        // TODO: Utwórz dwa obiekty Student, korzystając z danych wejściowych
        
        // TODO: Wypisz "Same reference: ", a następnie informację, czy student1 jest równy samemu sobie
        
        // TODO: Wypisz "Content equality: ", a następnie informację, czy student1 jest równy student2
        
        // TODO: Wypisz "Hash codes match: ", a następnie informację, czy obaj studenci mają ten sam kod skrótu
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online