Menu
CoddyTech

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() ma standardowy schemat: najpierw sprawdź, czy to ten sam obiekt, następnie zweryfikuj typ, a na koniec porównaj odpowiednie pola.

Za każdym razem, gdy nadpisujesz equals(), musisz również nadpisać hashCode(). To umowa w Javie: 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 na podstawie tych samych pól co 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

Zbudujmy 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 numer identyfikacyjny 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 prywatnymi polami: 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ą tę samą wartość studentId ORAZ tę samą wartość name. Zastosuj standardowy schemat: sprawdź, czy to ta sama referencja, sprawdź wartość null i 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 numer identyfikacyjny, imię i GPA pierwszego studenta, a następnie numer identyfikacyjny, 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 (zgodnie z implementacją equals)
    3. Wypisz Hash codes match: , a następnie informację, czy obaj studenci mają ten sam kod skrótu

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

Zwróć uwagę, że gdy dwóch studentów ma takie same numery identyfikacyjne i imiona, zarówno equals() zwraca true, JAK I ich kody skrótu są zgodne. Tę regułę musisz zachować!

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(); // pobierz 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 na podstawie 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 hash
    }
}
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