Sobes.tech
Middle

Kodėl perrašomi hashCode metodas ir lyginimo operatorius ==?

sobes.tech AI

Atsakymas iš AI

Perrašyti hashCode ir operatorių == (siekiant palyginti objektus pagal reikšmę, o ne nuorodą) būtina norint užtikrinti tinkamą heshavimo pagrindu veikiančių kolekcijų, tokių kaip HashSet ir HashMap, darbą.

  • Operatorius ==: Nustato, kada du objektai laikomi lygiais. Pagal numatytuosius nustatymus jis lygina nuorodas į objektus. Perrašydami jį, įgyvendiname logiką, kaip lyginti objektų turinį ar atributus.
  • Metodas hashCode: Grąžina sveikąjį skaičių (hesh kodą) objektui. Jei du objektai yra lygūs pagal operatorių ==, jų hesh kodai turi būti vienodi. Atvirkščiai tai nėra privaloma (du objektai gali turėti tą patį hesh kodą, bet būti nelygūs).

Šio kontrakto pažeidimas (lygūs objektai turi skirtingus hesh kodus) sukelia netinkamą heshuotų kolekcijų veikimą: elementai gali būti įtraukti kelis kartus ten, kur tikimasi unikalumo (HashSet), arba jų gali būti neįmanoma rasti (HashMap).

Pavyzdys:

class Person {
  final String name;
  final int age;

  Person(this.name, this.age);

  @override
  bool operator ==(Object other) {
    // Patikriname, ar kitas yra Person
    if (identical(this, other)) return true;
    if (other.runtimeType != runtimeType) return false;
    // Lyginame atributus
    return other is Person && name == other.name && age == other.age;
  }

  @override
  int get hashCode => Object.hash(name, age); // Generuojame hesh iš atributų
}

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

  print(p1 == p2); // true (reikšmės palyginimas po perrašymo)
  print(p1 == p3); // false

  final peopleSet = {p1};
  print(peopleSet.contains(p2)); // true (paieška pagal heshą ir palyginimą)
}