Menu
Coddy logo textTech

Sovrascrittura di hashCode e ==

Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 71 di 110.

Per impostazione predefinita, due oggetti in Dart sono uguali solo se sono esattamente la stessa istanza in memoria. Ciò significa che due oggetti con valori identici sono comunque considerati diversi:

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 - istanze diverse!
}

Per confrontare gli oggetti in base ai loro valori, devi eseguire l'override sia dell'operatore == sia di hashCode. Questi due devono sempre essere sovrascritti insieme: se due oggetti sono uguali, devono avere lo stesso codice hash:

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 - stessi valori!
}

hashCode è fondamentale per le raccolte come Set e per le chiavi di Map. Il metodo di supporto Object.hash() di Dart combina più valori in un singolo codice hash. Senza un hashCode corretto, i tuoi oggetti non funzioneranno correttamente nelle raccolte basate su hash, anche se viene fatto l'override di ==.

challenge icon

Sfida

Facile

Costruiamo un sistema di coordinate in cui i punti possano essere confrontati in base ai loro valori anziché ai loro indirizzi di memoria! Creerai una classe Coordinate che implementa correttamente l'uguaglianza basata sui valori, così da funzionare correttamente con i controlli di uguaglianza e con le raccolte basate su hash come Set.

Organizzerai il codice in due file:

  • coordinate.dart: crea una classe Coordinate che rappresenta un punto nello spazio 2D con i campi final int x e final int y. Esegui l'override sia dell'operatore == sia di hashCode, in modo che due coordinate con gli stessi valori di x e y siano considerate uguali. Usa Object.hash() per generare il codice hash a partire da entrambi i campi.
  • main.dart: importa il tuo file delle coordinate e mostra come l'uguaglianza basata sui valori modifica il comportamento del confronto tra oggetti:
    • Crea due oggetti Coordinate distinti, entrambi con x: 5 e y: 10
    • Stampa se sono uguali usando ==
    • Stampa se sono identici (la stessa istanza) usando identical()
    • Crea un Set<Coordinate> e aggiungici entrambe le coordinate
    • Stampa la lunghezza dell'insieme (dovrebbe essere 1, dato che sono uguali!)
    • Crea una terza coordinata con x: 3 e y: 7, e aggiungila all'insieme
    • Stampa la lunghezza finale dell'insieme

Questa sfida dimostra perché hashCode e == devono sempre essere sottoposti a override insieme. Set usa i codici hash per organizzare gli elementi, quindi senza un hashCode appropriato, anche gli oggetti uguali potrebbero essere memorizzati come duplicati!

Output previsto:

true
false
1
2

Provalo tu

import 'coordinate.dart';

void main() {
  // TODO: Crea dos objetos Coordinate distintos, ambos con x: 5 e y: 10

  // TODO: Imprime si son iguales usando ==

  // TODO: Imprime si son idénticos (la misma instancia) usando identical()

  // TODO: Crea un Set<Coordinate> y agrega ambas coordenadas

  // TODO: Imprime la longitud del conjunto (¡debería ser 1 porque son iguales!)

  // TODO: Crea una tercera coordenada con x: 3 e y: 7 y agrégala al conjunto

  // TODO: Imprime la longitud final del conjunto
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Dart online