שאלת מבחן בתכנות מונחה עצמים - אוניברסיטת בר-אילן 2014 - גנריות

נרצה לממש מחלקה המאפשרת מעבר על זוגות עוקבים של איברים ברשימה (List). למשל, עבור הקוד הבא:

הפלט יהיה:

1,2

2,3

3,4


מימוש המחלקה Pair נתון לכם:


א. איזה ממשק צריכה המחלקה PairsFrom לממש? (מה שמו, ומה השיטות שעליו להכיל) (5 נקודות)
ב. ממשו את המחלקה PairsFrom וכל מחלקה נוספת הנדרשת כדי לקבל את ההתנהגות הדרושה. (15 נקודות)
העתק שאלה
שתף שאלה
סמן כחשוב
סמן כבוצע
אוניברסיטת בר-אילןמועד ב2014סמסטר ב
גנריותממשקיםאיטרטוריםמחלקותמעקב אחר קוד
כדי לאפשר שימוש בלולאת for-each, על המחלקה לממש את הממשק Iterable. מתודת ה-iterator שלו צריכה להחזיר אובייקט Iterator המכיל את הלוגיקה של המעבר, ובפרט את המתודות hasNext ו-next.
א.
כדי שניתן יהיה להשתמש בלולאת for-each (שנקראת גם enhanced for loop) על אובייקט, המחלקה של אותו אובייקט חייבת לממש את הממשק `java.lang.Iterable<T>`. במקרה שלנו, הלולאה מחזירה בכל איטרציה אובייקט מהטיפוס Pair<Integer>, ולכן המחלקה הגנרית PairsFrom<E> צריכה לממש את הממשק `Iterable<Pair<E>>`.


ממשק זה מכיל מתודה אחת בלבד:
public Iterator<Pair<E>> iterator()


מתודה זו מחזירה אובייקט המממש את הממשק `Iterator<Pair<E>>`, אשר אחראי על הלוגיקה של המעבר על האיברים.


ב.
נממש את המחלקה PairsFrom<E> כך שתממש את הממשק Iterable<Pair<E>>. המתודה iterator() תחזיר מופע של מחלקה פנימית (inner class) שתממש את הממשק Iterator<Pair<E>> ותכיל את לוגיקת המעבר על הזוגות.


מימוש הקוד:


הסבר:
1. `PairsFrom<E>`: מחלקה גנרית המקבלת List<E> בקונסטרוקטור ושומרת אותו. היא מממשת את `Iterable<Pair<E>>`.

2. `iterator()`: המתודה היחידה של Iterable. היא מייצרת ומחזירה אובייקט חדש מסוג PairIterator. יצירת אובייקט חדש בכל קריאה מאפשרת להריץ מספר לולאות for-each במקביל על אותו אובייקט PairsFrom מבלי שהן יתנגשו.

3. `PairIterator`: זוהי מחלקה פנימית המממשת את `Iterator<Pair<E>>`. כמחלקה פנימית, יש לה גישה לשדה list של המחלקה החיצונית PairsFrom.

4. `currentIndex`: שדה במחלקה PairIterator העוקב אחר האינדקס של האיבר *הראשון* בזוג הבא שיוחזר.

5. `hasNext()`: מחזירה true כל עוד ניתן ליצור זוג. זוג מורכב מהאיברים במקום currentIndex ו-currentIndex + 1. לכן, הבדיקה היא האם האינדקס currentIndex + 1 עדיין נמצא בתחומי הרשימה.

6. `next()`: מחזירה את הזוג הבא. היא יוצרת Pair מהאיברים במקומות currentIndex ו-currentIndex + 1, מקדמת את currentIndex ב-1, ומחזירה את הזוג שנוצר. אם hasNext() מחזיר false, היא זורקת NoSuchElementException כנדרש בחוזה של `Iterator`.