Redéfinition de hashCode et ==
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy. Leçon 71 sur 110.
Par défaut, deux objets en Dart ne sont égaux que s'ils sont la même instance exacte en mémoire. Cela signifie que deux objets ayant des valeurs identiques sont toujours considérés comme différents :
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 - instances différentes !
}Pour comparer des objets par leurs valeurs, vous devez redéfinir à la fois l'opérateur == et hashCode. Ces deux-là doivent toujours être redéfinis ensemble - si deux objets sont égaux, ils doivent avoir le même code de hachage :
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 - mêmes valeurs !
}Le hashCode est crucial pour les collections comme les clés de Set et Map. L'assistant Object.hash() de Dart combine plusieurs valeurs en un seul code de hachage. Sans un hashCode approprié, vos objets ne fonctionneront pas correctement dans les collections basées sur le hachage, même si == est redéfini.
Défi
FacileConstruisons un système de coordonnées où les points peuvent être comparés par leurs valeurs plutôt que par leurs adresses mémoire ! Vous allez créer une classe Coordinate qui implémente correctement l'égalité basée sur les valeurs, ce qui lui permettra de fonctionner correctement avec les vérifications d'égalité et les collections basées sur le hachage comme Set.
Vous organiserez votre code en deux fichiers :
coordinate.dart: Créez une classeCoordinatereprésentant un point dans un espace 2D avec des champsfinal int xetfinal int y. Surchargez à la fois l'opérateur==ethashCodeafin que deux coordonnées ayant les mêmes valeurs x et y soient considérées comme égales. UtilisezObject.hash()pour générer le code de hachage à partir des deux champs.main.dart: Importez votre fichier de coordonnées et démontrez comment l'égalité basée sur les valeurs modifie le comportement de comparaison des objets :- Créez deux objets
Coordinatedistincts, tous deux avec x :5et y :10 - Affichez s'ils sont égaux en utilisant
== - Affichez s'ils sont identiques (même instance) en utilisant
identical() - Créez un
Set<Coordinate>et ajoutez-y les deux coordonnées - Affichez la longueur de l'ensemble (elle devrait être 1 puisqu'ils sont égaux !)
- Créez une troisième coordonnée avec x :
3et y :7, ajoutez-la à l'ensemble - Affichez la longueur finale de l'ensemble
- Créez deux objets
Ce défi démontre pourquoi hashCode et == doivent toujours être surchargés ensemble. Le Set utilise les codes de hachage pour organiser les éléments, donc sans un hashCode approprié, même des objets égaux pourraient être stockés comme des doublons !
Résultat attendu :
true
false
1
2Essayez vous-même
import 'coordinate.dart';
void main() {
// TODO: Créer deux objets Coordinate distincts, tous deux avec x: 5 et y: 10
// TODO: Afficher s'ils sont égaux en utilisant ==
// TODO: Afficher s'ils sont identiques (même instance) en utilisant identical()
// TODO: Créer un Set<Coordinate> et y ajouter les deux coordonnées
// TODO: Afficher la longueur de l'ensemble (devrait être 1 puisqu'ils sont égaux !)
// TODO: Créer une troisième coordonnée avec x: 3 et y: 7, l'ajouter à l'ensemble
// TODO: Afficher la longueur finale de l'ensemble
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesBibliothèques et importsIntroduction à la POOClasses vs objetsLe mot-clé thisMéthodesVariables d’instanceBases des constructeursRécapitulatif - Calculatrice simple4Sécurité face aux valeurs nulles
Introduction à la sécurité face aux valeurs nullesNullable vs Non-NullableLes opérateurs ? et !Mot-clé Late et sécurité face aux valeurs nullesOpérateurs sensibles à nullSécurité face aux valeurs nulles dans les classesRécapitulatif – Système de profil utilisateur7Classes abstraites et interfaces
Classes abstraitesMéthodes abstraitesInterfaces en DartInterfaces implicitesImplémenter ou étendreInterfaces multiplesRécapitulatif - Calculateur de formes10Collections et génériques
Vue d’ensemble des List, Set et MapCollections à typage sûrClasses génériquesMéthodes génériquesContraintes génériquesIterable et IteratorRécapitulatif – stockage générique2Constructeurs en Dart
Constructeur par défautConstructeurs nommésListes d'initialisationConstructeurs constantsConstructeurs factoryConstructeurs redirigésRécapitulatif - Constructeur de formes5Encapsulation
Membres publics vs privésLa convention du préfixe _Confidentialité au niveau de la bibliothèqueApprofondissement des getters et settersMasquage de l’informationRécapitulatif - Fiches des étudiants8Mixins
Introduction aux MixinsCréer des MixinsUtiliser plusieurs MixinsMot-clé on dans les MixinsMixin ou héritageMixin ou interfaceRécapitulatif - Système animal11Méthodes spéciales
Redéfinition de toString()Redéfinition de hashCode et ==Interface ComparableMéthode call()Redéfinition de noSuchMethodRécapitulatif - Collection personnalisée14Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron Strategy3Propriétés des classes
Membres d’instance et statiquesChamps Final et ConstVariables différéesMéthodes et champs statiquesAccesseurs et mutateursRécapitulatif - Gestionnaire de compte bancaire6Héritage
Héritage de baseLe mot-clé superRedéfinition de méthodeL’annotation @overrideLe mot-clé de classe finalConstructeurs et héritageRécapitulatif – Hiérarchie des employés9Polymorphisme
Bases du polymorphismePolymorphisme via les interfacesVérification des types à l’exécutionLes opérateurs is et asMot-clé covariantRécapitulatif - Processeur de paiements12POO asynchrone
Futures et async/awaitNotions de base des StreamsContrôleurs de StreamsConstructeurs asynchronesAsynchrone dans les méthodes de classeRécapitulatif - récupérateur de données15Patrons de conception – Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron CompositePatron DépôtEntraînez-vous par vous-même : Compilateur Dart en ligne