11- collections and generics

Download Report

Transcript 11- collections and generics

‫תכנות מכוון עצמים ושפת ‪JAVA‬‬
‫הרצאה ‪11‬‬
‫‪ Generics‬ואוספים‬
‫‪© Keren Kalif‬‬
‫ביחידה זו נלמד‪:‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪2‬‬
‫מהם אוספים‬
‫האוסף ‪Vector‬‬
‫האוסף ‪Set‬‬
‫האוסף ‪Map‬‬
‫המחלקה ‪Collections‬‬
‫‪© Keren Kalif‬‬
‫מחלקת מערך שיודעת‬
‫להגדיל את עצמה‬
‫החסרון במחלקה זו שהיא מתאימה‬
‫רק עבור הטיפוס ‪ int‬ונצטרך לשכפל‬
‫אותה עבור כל אחד מהטיפוסים‪..‬‬
‫הגדלת המערך‬
‫במידה ואין מקום‪...‬‬
‫שיטה זו הינה שיטת עזר‬
‫למחלקה ולכן ב‪private -‬‬
‫‪3‬‬
‫‪© Keren Kalif‬‬
‫שימוש במערך שיודע להגדיל את עצמו‬
‫השימוש במחלקה ‪ Array‬מאוד נוח‪...‬‬
‫‪4‬‬
‫‪© Keren Kalif‬‬
‫אוספים‬
‫‪ ‬אוסף הינו מבנה נתונים המאפשר לנו להחזיק כמות כלשהי של‬
‫איברים בעלי מכנה משותף‬
‫‪ ‬שפת ‪ JAVA‬מספקת לנו מחלקות מובנות המאפשרות לנו‬
‫להשתמש בכל מיני סוגי אוספים‪ ,‬ובפרט המחלקה ‪Vector‬‬
‫שתפקידה לשמש כמערך שאינו מוגבל בגודלו‬
‫‪ ‬במימוש האוספים ע"י ‪ JAVA‬ישנו שימוש במנגנון הנקרא‬
‫‪ generics‬שבו למעשה כותבים את המחלקה פעם אחת‪,‬‬
‫ומעבירים כפרמטר ב‪ > < -‬את הטיפוס של אוסף הנתונים‬
‫‪ ‬הטיפוס חייב להיות שם של מחלקה ולא טיפוס בסיסי‬
‫‪ ‬למשל‪ Integer :‬ולא ‪int‬‬
‫‪ ‬נהוג גם לקרוא לאוסף בשם ‪container‬‬
‫‪5‬‬
‫‪© Keren Kalif‬‬
‫דוגמא לשימוש במחלקה המובנית ‪Vector‬‬
‫טיפוס איברי המערך הוא מחלקה‬
‫‪10‬‬
‫הגודל הפיזי ההתחלתי‬
‫של המערך הוא ‪10‬‬
‫‪0‬‬
‫‪10‬‬
‫‪2‬‬
‫ניתן לראות כי ברגע שהמקום במערך‬
‫נגמר המחלקה מגדילה אותו פי ‪2‬‬
‫‪20‬‬
‫‪11‬‬
‫]‪[5, 2, 3, 4, 1, 7, 2, 9, 0, 4, 7‬‬
‫‪6‬‬
‫‪© Keren Kalif‬‬
‫‪F‬‬
‫‪T‬‬
‫מחלקות העוטפות טיפוסים בסיסיים‬
‫‪ ‬עבור כל אחד מהטיפוסים הבסיסיים ישנה מחלקה שעוטפת אותו‪,‬‬
‫כדי שנוכל להשתמש בה במקרה הצורך‪ ,‬למשל כפרמטר למחלקה‬
‫‪vector‬‬
‫‪ ‬אובייקטים אלו הם מסוג ‪ ,immutable‬כלומר לא ניתן לשנות‬
‫אותם‪.‬‬
‫‪ ‬כל שינוי למעשה מייצר אובייקט חדש (כמו ‪ ,)String‬ולכן העבודה‬
‫איתם יכולה להיות לא כ"כ יעילה‬
‫‪ ‬לכן במקרים בהם נרצה לשנות את איברי הוקטור שאיברים בסיסיים‬
‫באופן תדיר‪ ,‬נעדיף להשתמש דווקא במערך‬
‫‪7‬‬
‫‪© Keren Kalif‬‬
:‫תזכורת‬
Point ‫המחלקה‬
© Keren Kalif
8
‫דוגמא‬
‫קבלת הפניה לאיבר בוקטור‬
‫ושינוי ערכו‪ .‬השינוי משפיע‬
‫על האיבר שבוקטור‪.‬‬
‫קבלת הפניה לאיבר בוקטור‬
‫ושינוי ערכו‪ .‬השינוי אינו‬
‫משפיע על האיבר שבוקטור‪.‬‬
‫‪9‬‬
‫‪© Keren Kalif‬‬
‫האם הוקטור מחזיק את האיברים כהפניות‬
‫או כהעתקים??‬
‫ניתן לראות כי הוקטור מחזיק הפניות לאיברים‪ ,‬ואם‬
‫רוצים העתק יחודי לאובייקט בתוך המערך‪ ,‬יש לשלוח‬
‫באמצעות ‪( new‬מעבר ב‪ )copy c’tor -‬או ‪clone‬‬
‫])‪[(1, 1), (2, 2), (1, 1‬‬
‫])‪[(5, 1), (2, 2), (1, 1‬‬
‫‪© Keren Kalif 10‬‬
‫‪T‬‬
‫ניתן לראות כי השיטה ‪ contains‬בודקת האם‬
‫איבר קיים באמצעות השיטה ‪ equals‬ולא ==‬
‫(בודקת תוכן ולא הפניה)‬
‫המחלקה ‪Vector‬‬
‫‪ ‬בלינק הבא ניתן למצוא את התיעוד למחלקה‪:‬‬
‫‪http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html‬‬
‫‪ ‬ניתן לראות כי המחלקה מממשת‪ ,‬בין היתר‪ ,‬את הממשק‬
‫‪Collection‬‬
‫‪© Keren Kalif 11‬‬
‫הממשק ‪Collection‬‬
‫‪ ‬ממשק זה מגדיר את כל השיטות שהגיוני שיהיו לאוסף‬
‫‪ ‬ניתן לקרוא על כל אחת מהשיטות בתיעוד של הממשק‪:‬‬
‫‪http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collection.html‬‬
‫‪© Keren Kalif 12‬‬
‫המחלקה ‪Iterator‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫על איבריו של ‪ Vector‬ניתן לעבור בלולאה רגילה כמו שעוברים על‬
‫מערך‬
‫ישנם אוספים אשר לא מאפשרים מעבר באמצעות [ ] אלא‬
‫באמצעות אובייקט הנקרא איטרטור )‪ (Iterator‬שהוא למעשה‬
‫הפניה לאיבר כלשהו באוסף‬
‫לכל אוסף יש את השיטה )(‪ iterator‬המחזירה איטרטור לאיבר‬
‫הראשון באוסף‬
‫לאובייקט מטיפוס איטרטור יש ‪ 2‬שיטות המאפשרות לעבור על כל‬
‫איברי האוסף‪:‬‬
‫‪ hasNext ‬המחזירה ‪ true‬במידה ויש איברים נוספים‬
‫‪ next ‬המחזירה את ערך האיבר הבא‬
‫‪© Keren Kalif 13‬‬
‫דוגמאת שימוש ב‪-‬‬
‫‪Iterator‬‬
‫קבלת איטרטור לאיבר‬
‫הראשון באוסף‬
‫כל עוד יש איברים באוסף‬
‫קבלת האיבר הבא‬
‫‪© Keren Kalif 14‬‬
‫הגדרת‬
‫איטרטור‬
‫מטיפוס‬
‫איברי‬
‫האוסף‬
‫מבנה הנתונים ‪Set‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪( Set‬קבוצה) הינו אוסף שמכיל כל ערך פעם אחת בלבד‪ ,‬כלומר‬
‫לא יתכנו כפילויות של הערכים‬
‫ניסיון הוספה של ערך שכבר קיים לא יבוצע‬
‫‪ Set‬הינו ממשק לכל המחלקות הרוצות לממש מבנה נתונים זה‬
‫ההבדל בין המחלקות השונות הממשות מבנה נתונים זה הוא‬
‫הדרך בה הן מחזיקות את המידע (רשימה מקושרת‪ ,‬עץ וכד')‬
‫‪© Keren Kalif 15‬‬
‫דוגמאת שימוש ב‪set -‬‬
‫השיטה ‪ add‬מחזירה ‪ true‬במידה‬
‫והערך הוכנס לאוסף‪ false ,‬אחרת‬
‫‪ LinkedHashSet‬הינה מחלקה המממשת את הממשק‬
‫‪ set‬והיא שומרת את האיברים לפי סדר הכנסתם‬
‫‪ TreeSet‬הינה מחלקה המממשת את הממשק‬
‫‪ set‬והיא שומרת את האיברים ממוינים‬
‫‪© Keren Kalif 16‬‬
‫‪ Set‬שאיבריו הם אובייקט‬
‫ניתן לראות כי איבר נכנס לאוסף רק אם‬
‫עדיין אין הפניה אליו (כלומר בדיקה האם‬
‫איבר קיים הינה באמצעות == ולא ‪(equals‬‬
‫‪© Keren Kalif 17‬‬
‫‪ Set‬של אובייקטים ללא כפילויות בערכים‬
‫‪ ‬כל אובייקט מקבל בירושה מ‪ Object -‬את המתודה ‪hashCode‬‬
‫‪ ‬ניתן לדרוס אותה על‪-‬מנת לקבל ‪ int‬המזהה את האובייקט באופן חד‪-‬‬
‫חד ערכי‬
‫‪ ‬כל שני אובייקטים שערכיהם שווים יהיו בעלי ערך ‪ hashCode‬זהה‬
‫‪ ‬יתכן ו‪ 2 -‬אובייקטים עם ערכים זהים יקבלו ערך ‪ hashCode‬זהה‬
‫‪ ‬שימושי כאשר האובייקט נמצא בתוך אוסף שיש לזהות את‬
‫האובייקטים עפ"י ערכם‪ ,‬ולא בהכרח עפ"י הפנייתם‬
‫‪ ‬כאשר מחלקה מממשת את המתודה ‪ hasCode‬האוסף ‪ Set‬בודק‬
‫כפילויות באמצעות ‪ hasCode‬ולא באמצעות ==‪ ,‬כך שלא יתכנו ‪2‬‬
‫אובייקטים עם ערכים זהים‬
‫‪© Keren Kalif 18‬‬
‫דוגמא‬
© Keren Kalif 19
‫תמיכה במיונים לפי קריטריונים שונים‬
‫‪ ‬במידה ונרצה להחזיק אוסף ממויין‪ ,‬מבלי לייצר הצמדה בין הטיפוס‬
‫לאופן ההשוואה‪ ,‬משתמש ב‪Comparator -‬‬
‫‪ ‬בשפת ‪ C‬השתמשנו במצביעים לפונקציות‬
‫‪© Keren Kalif 20‬‬
‫דוגמא‬
© Keren Kalif 21
‫דוגמא‪:‬‬
‫השימוש‬
‫‪© Keren Kalif 22‬‬
‫מבנה הנתונים ‪Map‬‬
‫‪ map ‬הינו אוסף המאפשר פניה לערך מסויים באמצעות מפתח‬
‫כלשהו‪ ,‬ולא בהכרח באמצעות אינדקס מספרי‬
‫‪ ‬ניתן גם להסתכל עליו כעל מערך‪ ,‬שהאינדקסים שלו אינם בהכרח‬
‫מטיפוס ‪int‬‬
‫‪ ‬נשתמש בו כאשר נרצה למפות ערכים ממפתח מסוים‪ ,‬לערך‬
‫אחר‬
‫‪ ‬כל מפתח יכול להופיע פעם בלבד‬
‫‪ ‬ניסיון הוספה למפתח קיים ידרוס את ערכו הקוד‬
‫‪ map ‬הינו ממשק לכל המחלקות הרוצות לממש מבנה נתונים‬
‫זה‬
‫‪© Keren Kalif 23‬‬
‫דוגמא ‪1‬‬
‫‪26/11/1978‬‬
‫‪Daphna‬‬
‫‪21/2/1974‬‬
‫‪Guy‬‬
‫‪30/4/1980‬‬
‫‪Jasmine‬‬
‫‪Value‬‬
‫‪ Map‬שהמפתח הוא‬
‫מחרוזת והערך תאריך‬
‫הוספת ערכים‬
‫באמצעות השיטה‬
‫‪ put‬המקבלת‬
‫מפתח וערך‬
‫מעבר על כל איברי המפה‬
‫‪© Keren Kalif 24‬‬
‫‪Key‬‬
‫שימו לב‪ Date :‬היא‬
‫מחלקה שאני כתבתי‪ ,‬ולא‬
‫המחלקה שב‪java.utils -‬‬
‫דוגמא ‪2‬‬
‫‪ get‬מקבלת ערך של מפתח‬
‫מסויים ומחזירה הפניה ל‪value -‬‬
‫אם קיים‪ ,‬אחרת מחזירה ‪null‬‬
‫שינוי ערך ההפניה‬
‫שקיבלנו משפיע‬
‫על ערכו ב‪map -‬‬
‫‪© Keren Kalif 25‬‬
‫דוגמא ‪3‬‬
‫בדיקה האם מפתח‬
‫מסויים קיים‬
‫בדיקה האם ערך‬
‫מסויים קיים (בדיקה‬
‫באמצעות ‪)equals‬‬
‫‪© Keren Kalif 26‬‬
‫דוגמא ‪4‬‬
‫הוספת ערך למפתח‬
‫קיים תדרוס את‬
‫הערך הקודם‬
‫גם פה בדיקת המפתח היא באמצעות‬
‫==‪ ,‬ואם רוצים שתבוצע באמצעות‬
‫‪ equals‬יש לדרוס את ‪hashCode‬‬
‫‪© Keren Kalif 27‬‬
‫‪MultiMap‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫הינה מחלקה המממשת את המממשק ‪ map‬אך מאפשרת יותר‬
‫מערך אחד לכל מפתח‬
‫קבלת ערכי מפתח מסויים תחזיר משתנה מהטיפוס ‪Collection‬‬
‫מחלקה זו אינה נמצאת בספריה הסטנדרטית של ‪ java.utils‬אלא‬
‫בתת‪-‬ספריה של ‪ org.apache‬שצריך לייבא לתוך הפרוייקט‬
‫חלופה ל‪ MultiMap -‬הינה ‪ map‬שה‪ value -‬שלו מטיפוס ‪Vector‬‬
‫‪© Keren Kalif 28‬‬
‫מימוש ספר‬
‫טלפונים (‪)1‬‬
‫‪© Keren Kalif 29‬‬
‫הנתונים הם בתוך מפה שהערך שלה הוא מערך‬
‘A’
‘A’
“assaf”, “amir"
‘B’
‘B’
“beni”
…
…
‘Z’
‘Z’
Key
“ziv”, “zodiak”
Value
© Keren Kalif 30
© Keren Kalif 31
main -‫ה‬
© Keren Kalif 32
Collections ‫המחלקה‬
‫ מחלקה זו מכילה אוסף שיטות סטטיות לעבודה עם אוספים‬
:‫ ניתן לקרוא על כל אחד מהשיטות בתיעוד המחלקה‬
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collections.html
:‫ השיטות הנפוצות‬
max, min, replaceAll, frequency, reverse, rotate, shuffle, sort 
© Keren Kalif 33
‫דוגמאות‬
Collections -‫לשימוש ב‬
© Keren Kalif 34
Collections ‫שימוש בממשקים במחלקה‬
‫ בטיפוס‬Comparable ‫ מניחה מימוש של הממשק‬Sort ‫ השיטה‬
‫איברי האוסף‬
‫ אם טיפוס איברי האוסף לא מימש ממשק זה תהיה שגיאה‬
‫קומפילציה‬
Bound mismatch: The generic method sort(List<T>) of type
Collections is not applicable for the arguments (LinkedList<Point>).
The inferred type Point is not a valid substitute for the bounded
parameter <T extends Comparable<? super T>>
© Keren Kalif 35
‫ביחידה זו למדנו‪:‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫מהם אוספים‬
‫האוסף ‪Vector‬‬
‫האוסף ‪Set‬‬
‫האוסף ‪Map‬‬
‫המחלקה ‪Collections‬‬
‫‪© Keren Kalif 36‬‬