Sobes.tech
Middle

Защо се преписват методите hashCode и операторът за сравнение ==?

sobes.tech AI

Отговор от AI

Преписването на hashCode и оператора == (за сравняване на обекти по стойност, а не по препратка) е необходимо за правилната работа на колекции, базирани на хеширане, като HashSet и HashMap.

  • Оператор == : Определя кога два обекта се считат за равни. По подразбиране сравнява референциите към обектите. Презаписвайки го, реализираме логика за сравнение по съдържание или атрибути на обекта.
  • Метод hashCode : Връща цяло число (хеш код) за обекта. Ако два обекта са равни според ==, техните hashCode трябва да са еднакви. Обратното не е задължително (два обекта могат да имат еднакъв hashCode, но да не са равни).

Неспазването на този контракт (равни обекти с различни hashCode) води до неправилна работа на хешираните колекции: елементите могат да бъдат добавени няколко пъти там, където се очаква уникалност (HashSet), или да не бъдат намерени (HashMap).

Пример:

class Person {
  final String name;
  final int age;

  Person(this.name, this.age);

  @override
  bool operator ==(Object other) {
    // Проверка дали other е Person
    if (identical(this, other)) return true;
    if (other.runtimeType != runtimeType) return false;
    // Сравняване на атрибутите
    return other is Person && name == other.name && age == other.age;
  }

  @override
  int get hashCode => Object.hash(name, age); // Генериране на хеш от атрибутите
}

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

  print(p1 == p2); // true (сравнение по стойност след преписване)
  print(p1 == p3); // false

  final peopleSet = {p1};
  print(peopleSet.contains(p2)); // true (търсене по хеш и сравнение)
}