Menu
Coddy logo textTech

דריסת hashCode ו־==

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Dart של Coddy. שיעור 71 מתוך 110.

כברירת מחדל, שני אובייקטים ב-Dart שווים רק אם הם בדיוק אותו מופע בזיכרון. פירוש הדבר הוא ששני אובייקטים בעלי ערכים זהים עדיין נחשבים שונים:

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 - מופעים שונים!
}

כדי להשוות בין אובייקטים לפי הערכים שלהם, צריך לדרוס גם את האופרטור == וגם את hashCode. תמיד צריך לדרוס את שניהם יחד — אם שני אובייקטים שווים, חייב להיות להם אותו קוד גיבוב:

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 - אותם ערכים!
}

ה־hashCode חיוני לאוספים כמו Set ולמפתחות של Map. פונקציית העזר Object.hash() של Dart משלבת כמה ערכים לקוד גיבוב יחיד. ללא hashCode תקין, האובייקטים שלך לא יפעלו כראוי באוספים המבוססים על גיבוב, גם אם == נדרס.

challenge icon

אתגר

קל

בואו נבנה מערכת קואורדינטות שבה אפשר להשוות בין נקודות לפי הערכים שלהן ולא לפי כתובות הזיכרון שלהן! תיצרו מחלקת Coordinate שמממשת כראוי שוויון מבוסס ערכים, כך שתפעל נכון בבדיקות שוויון ובאוספים מבוססי גיבוב כמו Set.

תארגנו את הקוד שלכם בשני קבצים:

  • coordinate.dart: צרו מחלקת Coordinate שמייצגת נקודה במרחב דו־ממדי, עם השדות final int x ו-final int y. דרסו גם את האופרטור == וגם את hashCode, כך ששתי קואורדינטות עם אותם ערכים של x ו-y ייחשבו שוות. השתמשו ב-Object.hash() כדי ליצור את קוד הגיבוב משני השדות.
  • main.dart: ייבאו את קובץ הקואורדינטות שלכם והדגימו כיצד שוויון מבוסס ערכים משנה את אופן ההשוואה בין אובייקטים:
    • צרו שני אובייקטים נפרדים מסוג Coordinate, שלשניהם x: 5 ו-y: 10
    • הדפיסו אם הם שווים באמצעות ==
    • הדפיסו אם הם זהים (אותו מופע) באמצעות identical()
    • צרו Set<Coordinate> והוסיפו אליו את שתי הקואורדינטות
    • הדפיסו את אורך הקבוצה (הוא אמור להיות 1, מכיוון שהן שוות!)
    • צרו קואורדינטה שלישית עם x: 3 ו-y: 7, והוסיפו אותה לקבוצה
    • הדפיסו את האורך הסופי של הקבוצה

האתגר הזה מדגים מדוע יש לדרוס תמיד יחד את hashCode ואת ==. ה-Set משתמש בקודי גיבוב כדי לארגן איברים, ולכן ללא hashCode מתאים, אפילו אובייקטים שווים עלולים להישמר ככפילויות!

פלט צפוי:

true
false
1
2

נסו בעצמכם

import 'coordinate.dart';

void main() {
  // TODO: צרו שני אובייקטים נפרדים מסוג Coordinate, שניהם עם x: 5 ו-y: 10

  // TODO: הדפיסו אם הם שווים באמצעות ==

  // TODO: הדפיסו אם הם זהים (אותו מופע) באמצעות identical()

  // TODO: צרו Set<Coordinate> והוסיפו אליו את שתי הקואורדינטות

  // TODO: הדפיסו את גודל הקבוצה (אמור להיות 1 כי הן שוות!)

  // TODO: צרו קואורדינטה שלישית עם x: 3 ו-y: 7, והוסיפו אותה לקבוצה

  // TODO: הדפיסו את הגודל הסופי של הקבוצה
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Dart אונליין