PracticU

אוספים - Collections - חלק 2

בלי כתוביותעם כתוביות
PracticU › קורס תכנות מתקדם - #Advanced .NET C › אוספים - Collections - חלק 2
מילון מושגים:
מחלקה - תבנית בתכנות מונחה עצמים שמגדירה אילו נתונים ופעולות יהיו לאובייקטים שנוצרים ממנה.
ArrayList - מבנה נתונים של רשימה דינמית שגודלה משתנה, הנפוץ בשפות כמו Java ו-C#.
אובייקט - יחידה בתכנות מונחה עצמים שמאגדת נתונים (תכונות) ופעולות (מתודות). נוצר בדרך כלל ממחלקה המשמשת כתבנית.
זיכרון - רכיב מהיר ונדיף שבו המחשב שומר נתונים ותוכניות בזמן ריצתם. תוכנו נמחק עם כיבוי המחשב.
C# - שפת תכנות מונחית עצמים של מיקרוסופט, המשמשת בעיקר לפיתוח יישומים על פלטפורמת .NET.
ממשק - נקודת מגע בין רכיבים: ממשק משתמש שבו אדם מפעיל תוכנה, או ממשק תכנותי שמגדיר אילו פעולות רכיב אחד חושף לאחר.
אינדקס - מבנה במסד נתונים שמאיץ חיפוש ושליפה. גם מספר המציין מיקום של איבר במערך.
פרמטר - ערך שמועבר לפונקציה או לפקודה כקלט, ומשפיע על אופן פעולתן ועל התוצאה שהן מחזירות.

אוספים - Collections - חלק 2
בשיעור הזה בונים אוסף מוצרים שמאפשר להוסיף, לחפש, למחוק ולמיין פריטים, ומראים מה חייבים לממש במחלקת המוצר כדי שכל הפעולות האלה יעבדו.
השלבים העיקריים
1. מחלקת מוצר: המחלקה Product מכילה קוד, שם ומחיר, ובנוסף דריסה של ToString שמציגה את שלושת השדות.
2. למה Remove לא מוחק: ב-ArrayList ההשוואה נעשית בעזרת Equals. הפונקציה של Object משווה כתובות זיכרון, ולכן שני מוצרים עם אותו תוכן נחשבים שונים אם לא דורסים אותה.
3. דריסת Equals: קודם בודקים שהאובייקט שהתקבל הוא Product או נגזרת שלו, ורק אחר כך משווים את הקוד. אם הבדיקה הראשונה נכשלת, C# לא ממשיך לבדיקה השנייה, ולכן אין צורך בקאסט בלי בדיקה.
4. GetHashCode: הפונקציה מחזירה את הקוד הייחודי של המוצר. כך אוסף Hashtable יכול להשתמש בקוד כמפתח, ולאחזר מוצר לפי הקוד שלו, למשל 400.
5. למה Sort נכשל: מיון לא משתמש ב-Equals, כי צריך לדעת אם פריט גדול, קטן או שווה לפריט אחר, ולא רק אם הוא זהה לו. לכן המחלקה מממשת את הממשק IComparable ואת הפונקציה CompareTo, שמחזירה מספר שלילי, אפס או מספר חיובי.
6. מיון לפי שם וחיפוש בינארי: CompareTo מחזיר את השוואת השמות. אחרי המיון BinarySearch מוצא את המוצר ומחזיר את האינדקס שלו, ואם המוצר לא קיים מוחזר מספר שלילי. החיפוש הבינארי דורש אוסף ממוין, אחרת הוא עלול לא למצוא מוצר שקיים.
7. IComparer למיון לפי מחיר: מחלקה מקוננת בשם ProductPriceComparer ממשת את IComparer ומשווה לפי המחיר. בהשוואת מספרים עשרוניים כדאי להשתמש ב-if ולא בקאסט לאינטג'ר, כי הקאסט מעגל ויוצר אי דיוקים.
8. מיון בסדר יורד: אפשר לכתוב מחלקה נפרדת לכל סדר, או מחלקה אחת עם פרמטר. הפתרון הברור יותר הוא enum בשם SortingOrder, כי הקורא רואה מיד אם המיון עולה או יורד, במקום true או false.
בסיום השיעור ברור מה צריך לממש במחלקה כדי שתשתתף באוסף: Equals, GetHashCode ו-IComparable, ואחריהם מחלקות השוואה ייעודיות לכל סוג מיון.
השיעור הבא בקורס: אוספים - Collections - חלק 3

פרקי ההרצאה: אוספים - Collections - חלק 2

  1. 00:00

    אוסף מוצרים מבוסס על List

  2. 00:51

    מחלקת Product לתיאור מוצר בודד

  3. 02:28

    הוספת מוצרים לרשימה והצגתם

  4. 04:48

    חיפוש מוצר ברשימה ו-BinarySearch

  5. 06:26

    מחיקת מוצר והבעיה בהשוואה

  6. 07:45

    מתודת Equals של מחלקת Object

  7. 09:04

    דריסת Equals להשוואה לפי קוד מוצר

  8. 13:22

    מתודת GetHashCode והקשר לאוספים

תמלול ההרצאה: אוספים - Collections - חלק 2

הטקסט המלא של הדקות הראשונות בהרצאה «אוספים - Collections - חלק 2» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.

  1. 00:09

    בואו נפתח פרויקט חדש לגמרי, בואו נקרא לו product collection והתפקיד שלו זה בעצם לאסוף מוצרים ואנחנו רוצים שתהיה לנו איזשהו קולקשן שמאפשר לנו לאסוף פריטים שכל פריט זה אובייקט פרודקט ואנחנו רוצים להשתמש עם הרייליסט מפני שאנחנו רוצים שתהיה לנו את היכולת להוסיף מוצרים ולהוציא מוצר גם מהאמצע אוקיי אז בואו ניקח קודם כל איזושהי

  2. 00:53

    מחלקה שמתארת מוצר בודד. למוצר בודד יש public name, train name, public decimal price, ובואו נניח שיש לנו גם איזשהו קוד, אפילו את הקוד נשים ראשון.

  3. 01:25

    נייצר איזשהו קונסטרקטור ריק, איזשהו קונסטרקטור שמקבל את הקוד של המוצר, את השם של המוצר ואת המחיר של המוצר. בצורה כזאת, בואו נדרוס את toString בכדי להציג את שלושת החבר'ה האלה.

  4. 02:07

    נחזיר String.format עם המחרוזת code, name ו-price בצורה כזאת. וכעת בנינו לנו איזושהי מחלקה שמהווה מוצר אחד ויחיד ואנחנו רוצים איזשהו קולקשן שיהיה מסוגל לאסוף את כל הפריטים במחלקה הזאת.

  5. 02:42

    אוקיי, בואו נשים את זה פה side by side, ניפטר מהחלונית של הסלושן אקספלורר ונבנה לעצמנו איזשהו ארייליסט ומה בעצם אנחנו רוצים להוסיף אנחנו רוצים להתחיל להוסיף מספר מוצרים אז בואו נלך לאייטמס אד ונוסיף ניו פרודקט וניתן לו את הערכים קוד 100 ניים אפל ומחיר 3.5M מפני שזה דצימל אז בקיצור של מאני ובואו

  6. 03:35

    נוסיף גם גם בננה, 4.2, נוסיף פיצ' 2.7 ובואו נוסיף גם אורנג' וזה יהיה 5.1. אחלה, בואו נריץ for each, כל אחד מהפריטים זה פרודקט ולכן אנחנו יכולים לרוץ עליו עם פרודקט ונציג את הטו-ליסט שלו, טו-סטרינג ליתר דיוק, בואו נריץ ונראה שיש לנו פה את הפריטים, 100, 200, 300, 400,

  7. 04:30

    אפל, בננה, פיץ', אורנג' וכולי, הכל מוצג כמו שצריך. אבל בואו נראה האם באמת אנחנו יכולים עכשיו לעבוד עם היכולות האמיתיות שיש ל-realist.

  8. 04:45

    אז דבר ראשון, מה שאני רוצה לעשות, אני רוצה לעשות את הדבר הכי פשוט, אני רוצה ליצור עוד מוצר אחד, product שווה new product, ואני רוצה לקחת את אותם הערכים שיש בוא נניח למוצר הזה.

  9. 05:03

    וזה אומר שיש לי כרגע מוצר זהה לאחד המוצרים שקיימים באוסף. ומה שאני רוצה לעשות, אני רוצה לחפש את המוצר הזה באוסף של המוצרים.

  10. 05:19

    בואו נראה אם יש לנו את הפונקציה הזאת. Items זה כל האוסף, נקודה. ובואו נחפש כאן, יש לנו רימוב שאנחנו יכולים להשתמש איתה. בואו נראה, יש לנו Binary Search, אבל בינארי סרץ' מקבל, הוא מתעסק עם אוסף שהוא ממויין, אנחנו רואים סורטד רייליסט, והוא מוצא לנו את האינדקס שלו, זה לא יעבוד כרגע, הוא כמובן יקרוס, אנחנו

  11. 05:56

    יכולים לטפל בזה. אינדקס, בינארי סרץ' מחזיר לנו את האינדקס, ואנחנו הולכים לראות אינדקס ואנחנו הולכים לראות שיכול להיות שתהיה פה איזושהי בעיה.

  12. 06:13

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

  13. 06:26

    אבל בואו ניקח משהו יותר פשוט מבינארי סרצ'. בואו ניקח את הפעולה הבאה, Items.Remove. ואנחנו באים ואומרים, הנה המוצר, אנחנו יודעים שהוא קיים בתוך האוסף ואנחנו רוצים שתמחק לנו אותו.

  14. 06:45

    ואנחנו רוצים לבצע הדפסה לפני והדפסה אחרי המחיקה ואנחנו רוצים לראות האם באמת הוא הצליח למחוק את המוצר הזה שהקוד שלו זה 300 השם שלו זה פיץ' והמחיר שלו זה 2.7 בואו נריץ ונראה שבשתי הדפסות קיים לנו המוצר שהקוד שלו זה 300 ולא התבצעה לנו שום מחיקה והשאלה זה למה לא התבצעה לנו מחיקה של המוצר הזה והתשובה איך בדיוק הרייליסט מוצאת את מה שאנחנו רוצים

  15. 07:26

    אז התשובה היא שהרייליסט רצה בעצם על האוסף, לוקחת את הפריט שלנו וקוראת לפונקציה equals. ופונקציית equals שמגיעה מהמחלקה object, שכמובן לכל אובייקט בדוטנט קיימת את הפונקציה הזאת כי כל האובייקטים יורשים מ-object, אז פונקציית equals משמשת להשוואה בין האובייקט ששלחנו

  16. 07:58

    לבין כל אחד מפריטי האוסף אבל אנחנו לא דרסנו את פונקציית איקוואלס ולכן המימוש של הפונקציית איקוואלס שמתבצע זה המימוש של אובייקט והמימוש של אובייקט כלומר פונקציית איקוואלס ששייכת למחלקה אובייקט מה שהיא עושה היא משווה כתובות של אובייקטים אם שני האובייקטים נמצאים בכתובות שונים,

  17. 08:36

    שתי הכתובות הן שונות, אז פונקציית Equals של Object מחזירה False. עכשיו, אנחנו רואים שאלה באמת אובייקטים שונים. הנה אובייקט ראשון שיצרנו, והנה אובייקט אחר לגמרי שנוצר על ידי אופרטור New, ובגלל שזה אובייקט אחר לגמרי, הוא נמצא בכתובת אחרת בזיכרון,

  18. 08:58

    אפילו שמבחינתנו זה אותו תוכן וזה אמור להיות אותו המוצר. פתרון, כל מה שאנחנו צריכים לעשות זה להתחיל להבין שאם אנחנו בונים מחלקה משלנו שהולכת להשתתף בקולקשנים, כדאי מאוד שנוסיף למחלקה תמיכה בקולקשנים ולהשתמש בתשתית המוכנה שdotnet משתמשת איתה.

  19. 09:24

    זאת אומרת, כדאי שנדרוס כל מיני פונקציות שהמערכת משתמשת איתה by default. אחת מהפונקציות היא equals, אז בואו נדרוס את equals. ומה שאנחנו צריכים להבין זה שequals ראינו את זה פעם באובג'קט אוריינטד במודול של אובג'קט אוריינטד מחזירה בוליאן בכדי לומר אם האובייקט שהיא קיבלה זהה לאובייקט הנוכחי שלנו.

  20. 09:56

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

  21. 10:20

    אז דבר ראשון, מה שהיינו עושים, מה שכדאי לנו לעשות זה להשוות את הטיפוסים עצמם. האם opt is product או נגזרת של product זה גם בסדר.

  22. 10:35

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

  23. 11:04

    אז כל מה שאנחנו צריכים לעשות זה לבדוק האם הקוד של האובייקט הנוכחי שלנו זהה אובג' נקודה קוד שאין לנו ולכן כדאי לבצע קאסטינג ולהגיע לקוד אבל בשלב הזה בוודאות אנחנו יכולים להפוך את האובייקט לפרודקט מפני שב-c-sharp אם הבדיקה השמאלית לא עברה בהצלחה באופרטור end c-sharp לא תמשיך לבדיקה הימנית כי אין שום צורך אז אנחנו נגיע לבדיקה הימנית

  24. 11:50

    רק אם הבדיקה השמאלית עברה בהצלחה וזה אומר שזה מוצר פרודקט. אוקיי, יש לנו כרגע את פונקציית Equals, בואו נבדוק עכשיו, נריץ ונראה שכעת מוצר 300 עם קוד 300 הצליח להימחק בהצלחה.

  25. 12:10

    אנחנו לא רואים אותו בהדפסה השנייה. בואו נעשה אפילו משהו מעניין נוסף. בואו נשים פה breakpoint ונריץ את הפרויקט ונראה שתוך כדי הריצה אנחנו עוצרים בברייק פוינט שנמצאת בתוך פונקציית Equals.

  26. 12:29

    איך זה יכול להיות? הרי אתם לא רואים בשום מקום שהתבצעה קריאה לפונקציית Equals על ידינו. אז בייסיקלי אנחנו יודעים שרימוב רצה וקוראת ל-Equals בשביל להשוות את המוצר שהיא קיבלה עם כל אחד מהמוצרים שנמצאים בתוך ה-Collection ולכן רימוב היא זאת שקוראת ל-Equals.

  27. 12:55

    אנחנו יכולים להמשיך להריץ ולראות שיש פה עוד פעם עצירה בתוכו ועוד פעם עצירה בתוך עד שנמצא המוצר ואז הוא נמחק כמובן. אז פה אנחנו רואים שפונקציית equals היא זאת שאנחנו צריכים לממש בכדי שהאובייקט שלנו ישתתף בהצלחה בתוך קולקשן וניתן יהיה להסיר אותו מהקולקשן.

  28. 13:22

    מה בקשר לפונקציה getHashCode? גט השקוד זאת פונקציה שראינו באובג'קט אוריינטד שמחזירה את המזהה הייחודי של האובייקט. במקרה שלנו זה הקוד של המוצר.

  29. 13:38

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

  30. 14:03

    ומה שהוא יעשה זה ייצור collection hash table ובואו נניח שהוא רוצה להוסיף את המוצרים עצמם, אז בואו נפתח פה מוצרים כאלה, product p1 שווה new product בצורה כזאת, נפתח פה מספר מוצרים,

לקורס המלא: קורס תכנות מתקדם ב‑#C ודוט-נט

ההרצאה הקודמת: אוספים - Collections - חלק 1

ההרצאה הבאה: אוספים - Collections - חלק 3

הרצאות קשורות מקורסים אחרים

  • שאילתת LINQ - על אוספים רגילים

קורסים נוספים במסלול

  • קורס WinForms - תוכנות רגילות בווינדוס
  • פרויקט מעשי ב-#C - בונים מחשבון פשוט
  • פרויקט מעשי ב-#C - ספר טלפונים
  • פרויקט מעשי ב-#C - תוכנת צייר
  • קורס ADO.NET - חיבור אתר למסד נתונים
  • קורס WCF - תקשורת למתקדמים בדוט-נט