Sobes.tech
Middle

Proč jsou přepisovány metody hashCode a operátor ==?

sobes.tech AI

Odpověď od AI

Přepsání hashCode a operátoru == (pro porovnání objektů podle hodnoty, nikoli podle odkazu) je nezbytné pro správnou funkci hashovaných kolekcí, jako jsou HashSet a HashMap.

  • Operátor == : Určuje, kdy jsou dva objekty považovány za rovné. Ve výchozím nastavení porovnává odkazy na objekty. Přepsáním implementujeme logiku porovnání podle obsahu nebo atributů objektu.
  • Metoda hashCode : Vrací celočíselnou hodnotu (hash kód) pro objekt. Pokud jsou dva objekty podle == rovné, jejich hashCode by měly být stejné. Opak je pravdou (dva objekty mohou mít stejný hashCode, ale být nerovné).

Porušení tohoto kontraktu (rovné objekty s různými hashCode) vede k nesprávnému chování hashovaných kolekcí: prvky mohou být přidány vícekrát tam, kde se očekává jedinečnost (HashSet), nebo je nelze najít (HashMap).

Příklad:

class Person {
  final String name;
  final int age;

  Person(this.name, this.age);

  @override
  bool operator ==(Object other) {
    // Kontrola, zda je other typu Person
    if (identical(this, other)) return true;
    if (other.runtimeType != runtimeType) return false;
    // Porovnání atributů
    return other is Person && name == other.name && age == other.age;
  }

  @override
  int get hashCode => Object.hash(name, age); // Vytváří hash z atributů
}

void main() {
  final p1 = Person('Alice', 30);
  final p2 = Person('Alice', 30);
  final p3 = Person('Bob', 25);

  print(p1 == p2); // true (porovnání podle hodnoty po přepsání)
  print(p1 == p3); // false

  final peopleSet = {p1};
  print(peopleSet.contains(p2)); // true (hledání podle hash a porovnání)
}