מעבר באלמנטים של ArrayList
הוצג| English | משמעות |
|---|---|
| ConcurrentModificationException/kənˈkʌrənt ˌmɒdɪfɪˈkeɪʃn ekˈsepʃn/ | ConcurrentModificationException |
בחר טרייבר (סיור) המתאים לשינוי הרצוי
- ל-ArrayList יש [2, 3, 4]. רוצה להכפיל כל ערך מאוחסן בשניים, תוך שמירה על מספר האלמנטים ללא שינוי.
- לופ אינדקסי יכול להשתמש ב-list.set(i, 2 * list.get(i)). הצבה x = 2*x ב-for (int x : list) משנה רק את משתנה הלופ המקומי.
בהתחלה מרשימה [2, 3, 4], רץ for (int x : list) { x = 2 * x; }. מהו ערך של list.get(1)?
רמת קושי 2/5 · 140 מטבעות + בונוס קטן בהשלמה הראשונה היום
הקצאת הערך הפרימיטיבי המקומי x אינה מחליפה את אובייקט Integer האחסון. האלמנט האמצעי ברשימה נשאר 3.
סיור ברשימה
- טרייבר ArrayList בדיוק כמו מאגר, אך עם המיתודים שלו. אינדקסי:
for (int i = 0; i < list.size(); i++) { ... list.get(i) ... } - לולאת For-each:
for (String s : list) { ... s ... }— נקיה לקריאת ערכים.size()(ולאlength) קובעת גבולות ללולאת אינדקסים.
אותו הדבר דפוסים
- סכום, ספירה, מינ/מקס וחיסול עובדים בדיוק כמו במאגרים. פשוט החלף
a[i]ב-list.get(i)ו-a.lengthב-list.size(). - המצטבר והלוגיקה של מקסימום/ספירה זהים. הכל שלמדת למעבר במערכות עובר גם כאן.
קריאה מול שינוי
- לולאה משופרת (enhanced loop) מעתיקה כל ערך אל המשתנה שלה. עבור ⟨
Integer⟩ רכיבים שנקראו כ-int x, הקצאה ל-xאינה מחליפה רכיב ברשימה; לולאה עם אינדקס יכולה להחליפו באמצעות ⟨set(i, x)⟩. - לשינויים מבניים (הוספה/הסרה), השתמש בלולאה אינדקסית בזהירות. קריאה היא פשוטה; הסרה בזמן עבר דורשת זהירות נוספת (בשיעור הבא).
חיבור סכום אלמנטים ב-ArrayList לפי אינדקס
גבול עם size(), קריאה עם get(i) (list = [10,20,30]).
התנון הנכון למעגל ממוחשב ב-ArrayList הוא...
רמת קושי 1/5 · 100 מטבעות + בונוס קטן בהשלמה הראשונה היום
ArrayList משתמש ב-size(); מערכים משתמשים ב-length.
Why should a program avoid direct structural changes during an ArrayList enhanced-for traversal?
רמת קושי 1/5 · 100 מטבעות + בונוס קטן בהשלמה הראשונה היום
ArrayList fail-fast behaviour is best-effort. Avoid unsafe traversal rather than relying on a guaranteed exception.
דפוסי עבר על המערך (סכום, ספירה, מקסימום) עובדים באותו אופן עבור ArrayList.
רמת קושי 1/5 · 100 מטבעות + בונוס קטן בהשלמה הראשונה היום
פשוט החליפו את a[i]/a.length ב-list.get(i)/list.size().
כדי להסיר אלמנטים בבטחה בעת עובר על רשימה, עליכם להשתמש ב...
רמת קושי 1/5 · 100 מטבעות + בונוס קטן בהשלמה הראשונה היום
לולאת for-each לא יכולה לבצע שינוי מבני; הלולאה עם האינדקס כן (בזהירות).
ללא שינוי מבני במהלך עבר, לולאה מוגברת יכולה לקרוא לכל הכניסות של anArrayList
רמת קושי 1/5 · 100 מטבעות + בונוס קטן בהשלמה הראשונה היום
הלולאה קוראת כל הייחוס המאוחסן. שינויים מבניים במהלך עבר הם נושא נפרד; הטענה זו אינה מבטיחה שהפעולות על כל אלמנט אפשרי יהיו בטוחות.
אל תשנה במהלך for-each
- הוספה או הסרה במהלך לולאת for-each עלולה להפעיל ConcurrentModificationException; זיהוי ה-"fail-fast" הוא ניסיון מיטבי. לולאת for-each מניחה שהרשימה לא משנה את המבנה תחתיה.
- להסרה בעת מעבר, השתמש בלולאה אינדקסית (וניהל את האינדקס). קריאה עם for-eck מתאימה כאשר הרשימה אינה משנה מבנית במהלך העבר. כמו כן, בדוק את דרישות האלמנט: unboxing של Integer שווה לnull עדיין זורם יוציאן.
גבול את לולאת אינדקס עלArrayList ב-list.size(), ולא ב-.length, ואל תשנה מבניתית בזמן for-each. קריאת add/remove בתוך for (x : list) עשויה לגרור ConcurrentModificationException, אך זיהוי אינו מובטח. למחיקה במהלך טיפוס, השתמש בלולאת אינדקס — וזכור ש-remove(i) מזז רכיבים מאוחרים, ולכן אל תעשה i++ עיוור לאחר הרכיב המוזז.
After the indexed doubling update, what is list.get(1)?
רמת קושי 2/5 · 140 מטבעות + בונוס קטן בהשלמה הראשונה היום
The middle stored value 3 is replaced by 6. Reassigning a primitive loop variable would leave it at 3.
לכניסות תלמיד שאינן null, s.addScore(5) בתוך for (Student s : students) יכול לשנות את התלמידים האחסונים ללא הוספה או הסרת אלמנטים מהרשימה.
רמת קושי 1/5 · 100 מטבעות + בונוס קטן בהשלמה הראשונה היום
היפניות המועתקות מגיעות לאובייקטי Student שניתן לשינוי. השדות שלהם יכולים להשתנות ללא שינוי במבנה הרשימה.
סכום של ArrayList
- אינדקסי:
for (int i = 0; i < list.size(); i++) { sum += list.get(i); } - For-each:
for (int x : list) { sum += x; }(autoboxing/unboxing מטפל ב-Integer↔int). - שתי הדרכים מסכמות את הרשימה; for-each נקי יותר לקריאה בלבד.
להעביר את הניתוח למקרה חדש
- הוספה או הסרה ישירה במהלך עבר מוגברת הוא לא בטוח; יוצאינים של type "fail-fast" הם ניסיון מיטבי, ולא בדיקת נכונות מובטחת.
- רשימה של אובייקטי Student משתנים יכולה להיות מעוברת עם
for (Student s : students) { s.addScore(5); }, בהנחת כניסות שאינן null. שינוי זה מצב כל אובייקט ללא שינוי במבנה הרשימה; הקצאה של רפרנס שונה לsלא תחליף את האלמנט הנשמר.
עבור ArrayList עם לולאת אינדקס (i < list.size(), list.get(i)) או לולאת מוגברת שמקבלת כל ערך אלמנט. דפוסי המערך (סכום, ספירה, מינימום/מקסימום, חיפוש) כולם עוברים. הימנע משינויים מבניים ישירים במהלך עבר מוגבר: ConcurrentModificationException עשוי לזהות את השגיאה, אך אינו מובטח. השתמש בלולאה אינדקסית המנוהלת בקפידה לדפוס ההסרה שנלמד בשיעור הבא; שינוי שדות של אובייקט ברפרנס שונה משינוי מבנה רשימה.