Menu
Coddy logo textTech

Nadpisanie hashCode i ==

Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 71 z 110.

Domyślnie dwa obiekty w Dart są równe tylko wtedy, gdy są dokładnie tą samą instancją w pamięci. Oznacza to, że dwa obiekty o identycznych wartościach nadal są uznawane za różne:

class Point {
  int x, y;
  Point(this.x, this.y);
}

void main() {
  var p1 = Point(3, 4);
  var p2 = Point(3, 4);
  print(p1 == p2);  // false - różne instancje!
}

Aby porównywać obiekty na podstawie ich wartości, musisz przeciążyć zarówno operator ==, jak i hashCode. Te dwa elementy zawsze należy przeciążać razem — jeśli dwa obiekty są równe, muszą mieć ten sam kod skrótu:

class Point {
  final int x, y;
  Point(this.x, this.y);
  
  @override
  bool operator ==(Object other) {
    if (other is! Point) return false;
    return x == other.x && y == other.y;
  }
  
  @override
  int get hashCode => Object.hash(x, y);
}

void main() {
  var p1 = Point(3, 4);
  var p2 = Point(3, 4);
  print(p1 == p2);  // true - te same wartości!
}

hashCode ma kluczowe znaczenie dla kolekcji takich jak Set oraz kluczy Map. Funkcja pomocnicza Object.hash() w Dart łączy wiele wartości w jeden kod skrótu. Bez prawidłowego hashCode obiekty nie będą działać poprawnie w kolekcjach opartych na kodach skrótu, nawet jeśli nadpisano ==.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system współrzędnych, w którym punkty można porównywać na podstawie ich wartości, a nie adresów pamięci! Utworzysz klasę Coordinate, która prawidłowo implementuje równość opartą na wartościach, dzięki czemu będzie działać poprawnie przy sprawdzaniu równości i w kolekcjach opartych na skrótach, takich jak Set.

Podzielisz kod na dwa pliki:

  • coordinate.dart: Utwórz klasę Coordinate reprezentującą punkt w przestrzeni 2D, z polami final int x i final int y. Przeciąż zarówno operator ==, jak i hashCode, aby dwie współrzędne o takich samych wartościach x i y były uznawane za równe. Użyj Object.hash(), aby wygenerować kod skrótu na podstawie obu pól.
  • main.dart: Zaimportuj plik ze współrzędnymi i pokaż, jak równość oparta na wartościach zmienia sposób porównywania obiektów:
    • Utwórz dwa osobne obiekty Coordinate, oba z x: 5 i y: 10
    • Wypisz, czy są równe, używając ==
    • Wypisz, czy są identyczne (ta sama instancja), używając identical()
    • Utwórz Set<Coordinate> i dodaj do niego obie współrzędne
    • Wypisz długość zbioru (powinna wynosić 1, ponieważ współrzędne są równe!)
    • Utwórz trzecią współrzędną z x: 3 i y: 7, a następnie dodaj ją do zbioru
    • Wypisz końcową długość zbioru

To wyzwanie pokazuje, dlaczego hashCode i == należy zawsze przeciążać razem. Set używa kodów skrótu do organizowania elementów, więc bez prawidłowego hashCode nawet równe obiekty mogą być przechowywane jako duplikaty!

Oczekiwany wynik:

true
false
1
2

Spróbuj swoich sił

import 'coordinate.dart';

void main() {
  // TODO: Utwórz dwa osobne obiekty Coordinate, oba z x: 5 i y: 10

  // TODO: Wypisz, czy są równe, używając ==

  // TODO: Wypisz, czy są identyczne (czy to ta sama instancja), używając identical()

  // TODO: Utwórz Set<Coordinate> i dodaj do niego obie współrzędne

  // TODO: Wypisz liczbę elementów zbioru (powinna wynosić 1, ponieważ są równe!)

  // TODO: Utwórz trzecią współrzędną z x: 3 i y: 7 i dodaj ją do zbioru

  // TODO: Wypisz końcową liczbę elementów zbioru
}
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 Dart online