Object.hashCode în Dart

Un număr asociat obiectului, folosit de Set și Map; obiectele egale cu == trebuie să aibă același hashCode.

Sintaxă
int get hashCode

Ce face Object.hashCode

hashCode este un număr calculat din obiect, folosit de colecțiile bazate pe hash (Set, Map, HashMap) ca să găsească rapid elementele. Regula de aur: dacă a == b, atunci a.hashCode == b.hashCode. Invers nu este obligatoriu: obiecte diferite pot avea același cod.

Implementarea implicită din Object se bazează pe identitate: fiecare obiect are codul lui, la fel ca == implicit. Dacă suprascrii == ca să compari după conținut, trebuie să suprascrii și hashCode, altfel Set și Map se comportă greșit. Cel mai simplu îl calculezi cu Object.hash.

Valoarea exactă poate diferi între rulări și între platforme. Nu o afișa, nu o salva și nu te baza pe ea în afara programului curent.

Ce returnează

Un int.

Exemple

Exemplul 1: == și hashCode împreună

PunctGresit suprascrie doar ==, deci setul păstrează două puncte „egale”. Punct suprascrie ambele metode și funcționează corect.

class PunctGresit {
  final int x, y;
  PunctGresit(this.x, this.y);
  @override
  bool operator ==(Object other) => other is PunctGresit && other.x == x && other.y == y;
  // lipsește hashCode!
}

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

void main() {
  print(PunctGresit(1, 2) == PunctGresit(1, 2));
  print({PunctGresit(1, 2), PunctGresit(1, 2)}.length);
  print(Punct(1, 2) == Punct(1, 2));
  print({Punct(1, 2), Punct(1, 2)}.length);
  print(Punct(1, 2).hashCode == Punct(1, 2).hashCode);
}

Rezultat

true
2
true
1
true

Exemplul 2: Valorile de bază respectă regula

Afișăm doar comparații, nu valorile, pentru că ele pot fi diferite de la o rulare la alta.

void main() {
  var a = 'Iași';
  var b = 'Ia' + 'și';
  print(a == b);
  print(a.hashCode == b.hashCode);
  print(7.hashCode == 7.hashCode);
  var lista1 = [1, 2];
  var lista2 = [1, 2];
  print(lista1 == lista2);
  print(lista1.hashCode == lista2.hashCode);
}

Rezultat

true
true
true
false
false

Greșeli frecvente

  • Suprascrii == fără hashCode. Obiectele egale ajung de două ori în Set, iar căutările în Map nu le găsesc.
  • Calculezi hashCode din câmpuri care se pot schimba. Dacă obiectul se modifică după ce a fost pus într-un Set, nu mai poate fi găsit. Folosește câmpuri final.

Comenzi înrudite

  • Object.hash: Combină codurile hash ale mai multor valori într-unul singur; hashAll face același lucru pentru o colecție.
  • identical: Verifică dacă două variabile arată spre exact același obiect din memorie, nu doar spre obiecte egale.
  • Object: Clasa de bază a tuturor claselor Dart, cu excepția lui Null; runtimeType dă tipul real al unui obiect.
  • Set: Colecție fără elemente duplicate: fiecare valoare apare o singură dată, iar căutarea este rapidă.