JavaRush /בלוג Java /Random-HE /ניתוח מפורט של המחלקה ArrayList [חלק 1]
Vonorim
רָמָה

ניתוח מפורט של המחלקה ArrayList [חלק 1]

פורסם בקבוצה
מאמר זה יסתכל מפורט על המחלקה ArrayList מתוך Collections Framework, שהיא אולי הקלה ביותר להבנה, בשל העובדה שהיא מבוססת על מערך רגיל. כמעט בוודאות תישאל שאלה לגבי השיעור הזה והטמעתו בג'אווה בראיון. בחלק השני ננתח את השיטות הנותרות ונכתוב יישום משלנו של מערך דינמי למספרים. המחלקה ArrayList יורשת מהמחלקה AbstractList ומיישמת את הממשקים הבאים: List, RandomAccess, Cloneable, Serializable. ניתוח מפורט של המחלקה ArrayList [חלק 2] ניתוח מפורט של המחלקה ArrayList [חלק 1] - 1 המחלקה ArrayList תומכת במערכים דינמיים הניתנים להרחבה לפי הצורך. נחיצותו ויעילותו מוסברים בכך שלמערך רגיל יש אורך קבוע: ברגע שהוא נוצר, הוא לא יכול לגדול או להתכווץ, מה שמטיל מגבלות אם לא ידוע כמה גדול יהיה צורך במערך. בעיקרו של דבר, המחלקה ArrayList היא מערך רשימה באורך משתנה של הפניות לאובייקטים. חשוב להבין שגודלו (מספר התאים) של המערך הפנימי אינו פוחת אוטומטית כאשר מסירים ממנו אלמנטים. למעשה, הערך של המשתנה size, המציין את מספר האלמנטים הקיימים בפועל במערך, ירד. נניח שאנו יוצרים אובייקט חדש של המחלקה ArrayList ונוסיף לו 5 אלמנטים. כברירת מחדל, נוצר מערך של 10 אלמנטים. במקרה זה, מה שנקרא הקיבולת (גודל/נפח) של האובייקט שלנו תהיה שווה ל-10, אבל הערך של המשתנה sizeיהיה שווה לחמישה. וכאשר אנו מוחקים אלמנטים, אנו רואים שינויים בערך של המשתנה size, מכיוון .lengthשאיננו יכולים לגשת למערך הפנימי של המחלקה ArrayList ולברר את אורכו. ניתן להקטין את הגודל באמצעות שיטה נוספת trimToSize(), עליה נדון בהמשך. בואו נסתכל על שדות הכיתה.
  • שדה האחראי לנפח ברירת המחדל של המערך הדינמי:

    private static final int DEFAULT_CAPACITY = 10

    בעת יצירת אובייקט חדש New ArrayList<>() (בנאי ללא פרמטרים), נוצר בתוכו מערך של 10 אלמנטים.

  • שדה שבו מאוחסנים כל רכיבי האוסף:

    transient Object[] elementData

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

  • שדה מונה המאחסן את מספר האלמנטים בפועל במערך:

    private int size

    הערך מוגדל/מופחת בעת ביצוע פעולות כגון הכנסה ומחיקה.

יש עוד 3 שדות בכיתה, אבל בעצם הם נוספים, אז אין טעם לשקול אותם. למחלקה יש שלושה בנאים:
  1. public ArrayList()- יוצר מערך רשימה ריק של 10 אלמנטים;
  2. public ArrayList(Collection < ? extends E > c)– יוצר מערך רשימות שאתחל עם אלמנטים מהאוסף שעבר (אם ברצוננו ליצור ArrayList חדש המבוסס על אוסף כלשהו);
  3. public ArrayList(int initialCapacity)– יוצר מערך רשימה עם קיבולת ראשונית. אם הפרמטר המועבר initialCapacity גדול מ-0, נוצר מערך בגודל שצוין (לאלמנט השדה הפנימי מוקצה קישור למערך חדש מסוג Object בגודל initialCapacity). אם הפרמטר הוא 0, אז נוצר מערך ריק. אם הפרמטר שצוין קטן מ-0, אזי נזרק IllegalArgumentException.
יצירת אובייקט
List < String> list = new ArrayList<>();
האובייקט החדש שנוצר listמכיל מאפיינים (שדות) elementDataו- size. מאגר ערך elementDataהוא לא יותר ממערך מסוג מסוים (המצוין בגנרי – <>), במקרה שלנו String[]. אם נקרא בנאי ללא פרמטרים, אז כברירת מחדל ייווצר מערך של 10 אלמנטים מסוג Object (עם יציקה לסוג, כמובן). ניתוח מפורט של המחלקה ArrayList [חלק 1] - 2הוספת אלמנטים באופן קלאסי הוספת אלמנטים למערך רשימה נעשית באמצעות גרסאות עמוסות יתר של ה- add().
public boolean add(E элемент)
ובכן, בואו נוסיף: list.add("0"); ניתוח מפורט של המחלקה ArrayList [חלק 1] - 3בתוך השיטה הזו, גרסה עמוסה מדי של השיטה נקראת add(), מסומנת בתור private, אשר בתורה לוקחת שלושה פרמטרים כקלט: האלמנט שיש להוסיף, המערך הפנימי וגודלו. בשיטה הפרטית מתרחשת בדיקה: אם פרמטר הגודל שעבר שווה לאורכו של המערך הפנימי (כלומר, המערך מלא), אזי למערך מוקצה תוצאת השיטה grow(int minCapacity)(הערך הנוכחי של השדה גודל + 1 מועבר לשיטה, מכיוון שיש צורך לקחת בחשבון את האלמנט המתווסף), שבה למערך הפנימי מוקצה קישור למערך החדש שנוצר על ידי העתקת האלמנטים של המערך המקורי:
Arrays.copyOf(elementData, newCapacity(minCapacity))
כפרמטר השני של השיטה, copyOfאנו מציינים את תוצאת השיטה newCapacity(int minCapacity), שבתוכה מחושב גודל המערך החדש. זה מחושב באמצעות הנוסחה הבאה: int newCapacity = oldCapacity + (oldCapacity >> 1) עבור מערך עם גודל ברירת המחדל, הדברים הבאים יהיו נכונים: >> 1– העברה סיבית ימינה באחד (אופרטור שמקטין מספר לחצי ממנו). בעיקרו של דבר, זה אומר לחלק ב-2 בחזקת 1. מסתבר שאנחנו מחלקים 10 ב-2 ומוסיפים 10. סך הכל, הקיבולת החדשה של המערך היא 15, אבל מכיוון שאנחנו מוסיפים את האלמנט ה-11, אז 15 + 1 = 16. נחזור לרשימה שלנו ונניח שכבר הוספנו לה 10 אלמנטים וננסה להוסיף 11. הסימון יראה שאין רווח במערך. בהתאם לכך, נוצר מערך חדש ונקרא Arrays.copyOf, אשר משתמש באופן פנימי בשיטת המערכת System.arraycopy(). ניתוח מפורט של המחלקה ArrayList [חלק 1] - 4ניתוח מפורט של המחלקה ArrayList [חלק 1] - 5או הנה דוגמה ברורה ממאמר אחד ב-JavaRush: ניתוח מפורט של המחלקה ArrayList [חלק 1] - 6אחרי כל הבדיקות האלה והגדלת גודל המערך במידת הצורך, אז בשיטה פרטית add()מתווסף אלמנט חדש לסוף המערך, והפרמטר הנוכחי sizeגדל באחד . המערך הישן יעובד לאחר מכן על ידי אספן האשפה. כך פועל מערך דינמי: כשאנו מוסיפים אלמנטים בודקים אם יש בו עדיין מקום. אם יש מקום, פשוט נוסיף את האלמנט לסוף המערך. הסוף אינו מתכוון לתא האחרון במערך, אלא לתא המתאים לערך size. הוספנו את האלמנט הראשון למערך; הוא ממוקם בתא עם אינדקס [0]. ערך השדה sizeגדל ב-1 ו=1. נוסיף את האלמנט הבא: אנו רואים כי size = 1, בהתאם אנו מניחים את האלמנט בתא עם אינדקס [1] וכן הלאה. יש גרסה עמוסה מדי של השיטה עם שני פרמטרים:
public void add(int index, E element)
נוכל לציין את המיקום (אינדקס) של התא שבו נרצה להוסיף את האלמנט. ראשית, נבדקת נכונות ערך האינדקס שצוין, שכן קיימת אפשרות שיצוין אינדקס שגוי, שיצביע על תא שאין בו כלום, או שפשוט אינו קיים. בדיקת אינדקסים: index > size || index < 0- אם האינדקס שצוין גדול מהגודל הנוכחי של המערך או שהוא קטן מ-0, אזי נזרק חריג IndexOutOfBoundsException. לאחר מכן, במידת הצורך, גדל המערך, בדומה לדוגמא שלמעלה. בטח שמעתם שבמהלך פעולות הוספה/הסרה במערך, משהו מוזז למקום כלשהו (או ימינה או שמאלה). אז, ההסטה מתבצעת על ידי העתקת המערך: System.arraycopy(elementData, index, elementData, index + 1, s - index); כל האלמנטים הממוקמים מימין לאינדקס שצוין יוזזו עמדה אחת ימינה (אינדקס+1). ורק לאחר מכן נוסף אלמנט חדש למערך הפנימי באינדקס שצוין. מכיוון שהסטנו חלק מהמערך ימינה באחד (לא נוצר מערך חדש), התא שאנו צריכים יהיה פנוי לכתיבה. הקישור למערך הישן נמחק ובעתיד ישתלט עליו אספן האשפה. הדבק "מזראטי" בתא [3], שכבר תפוס:
ניתוח מפורט של המחלקה ArrayList [חלק 1] - 7
לפיכך, כאשר אלמנט מוכנס באינדקס ואין רווחים פנויים במערך, הקריאה System.arraycopy()תתרחש פעמיים: הראשונה ב- grow(), השנייה בשיטה עצמה add(index, value), מה שישפיע בבירור על מהירות פעולת ההוספה כולה. כתוצאה מכך, כאשר יש צורך לכתוב אלמנט נוסף למערך הפנימי, אך אין שם רווח, אז זה מה שקורה בתוך ArrayList:
  • נוצר מערך חדש בגודל גדול פי 1.5 מהמקורי, בתוספת אלמנט אחד.
  • כל הרכיבים מהמערך הישן מועתקים למערך החדש
  • המערך החדש מאוחסן במשתנה הפנימי של אובייקט ArrayList, והמערך הישן מוכרז כזבל.
ניתן להגדיל את הקיבולת של אובייקטים מסוג ArrayList באופן ידני באמצעות השיטה:
public void ensureCapacity(int minCapacity)
על ידי הגדלת קיבולת המערך מראש, תוכל להימנע מחלוקה מחדש נוספת של זיכרון RAM מאוחר יותר. השיטה מגדילה את גודל המערך הפנימי כדי להכיל את מספר האלמנטים המועברים אל minCapacity. השיטה ensureCapacity()לא משפיעה על השדה size, היא משפיעה על capacity(גודל) המערך הפנימי. שוב אני מדגיש ששניהם sizeדברים capacityשונים וחשוב מאוד לא להתבלבל ביניהם! אם אתה רוצה להקטין את גודל המערך הבסיסי שממנו בנוי ה-ArrayList למספר הנוכחי של אלמנטים המאוחסנים בפועל, עליך לקרוא ל- trimToSize(). לאחר הסרת אלמנטים מהאוסף, size()הוא יציג את מספר האלמנטים הקיימים בפועל, capacityולא יקטן! נניח: הכנסנו 100 אלמנטים, מחקנו את ה-50 הראשונים, sizeזה ישתווה ל-50, וכך capacityזה יישאר 100. כדי לצמצם ו capacity, אנחנו צריכים להשתמש בשיטה trimToSize(), אשר מתאימה את כל הקיבולת שלנו לגודל הנוכחי. איך זה מתאים? מעתיק את המערך שלנו כך שלא יישארו תאים ריקים (אורך המערך החדש פשוט שווה לשדה הגודל).
ניתוח מפורט של המחלקה ArrayList [חלק 1] - 8
אתה יכול גם להוסיף אלמנטים לאוסף שלנו באמצעות addAll.
public boolean addAll(Collection< ? extends E> c)
public boolean addAll(int index, Collection< ? extends E> collection);
האפשרות הראשונה מאפשרת להוסיף את כל האלמנטים מהאוסף שצוין בפרמטר השיטה (לדוגמה, גיליון נוסף) לאוסף המקורי (הוספה בסוף) שעבורו בוצעה הקריאה למתודה. האוסף שעבר (זה יכול להיות גם סט) מומר למערך באמצעות ה- toArray(). מטבע הדברים, פעולת ההוספה מתבצעת גם באמצעות העתקה. השני הוא להוסיף את כל האלמנטים collectionלרשימה, החל מ- index index. במקרה זה, כל הרכיבים יעברו ימינה לפי מספר האלמנטים ברשימה collection. הסרת אלמנטים ראשית, בואו נסתכל על האפשרויות הקלאסיות להסרת אלמנטים מ-ArrayList.
public E remove(int index)
מבצע מחיקה לפי אינדקס ומזיז את כל האלמנטים הבאים (אחרי האלמנט באינדקס שצוין) שמאלה, ובכך סוגר את ה"חורים". היא גם מחזירה את האלמנט שנמחק (E), שנכתב בעבר למשתנה נוסף לפני המחיקה, שאת ערכו נקבל כתוצאה מקריאה למתודה. כדי להבין מהו E, תצטרך להכיר את מה שנקרא סוגים גנריים. הסימון E מציין שהמתודה מחזירה את סוג הנתונים שצוין בעת ​​יצירת האובייקט ArrayList (זכור: List <String> list, בהתאם, במקרה זה, E "יוחלף" String). להבנה כללית, אני ממליץ לך בחום להכיר טיפוסים גנריים. נבדקת נכונות האינדקס שהוזן, ואז בתוך השיטה האלמנט לא נמחק לגמרי, אלא שיטה פרטית נקראת fastRemove(Object[] es, int i), שבה המחיקה כבר מתרחשת. אנו מעבירים את המערך שלנו ואת האינדקס שצוין לשיטה כקלט. האלמנטים מועתקים באמצעות System.arraycopy(), גודל המערך מצטמצם, ואז אנו מקצים null לאלמנט האחרון. ראוי לציין שלא נוצר מערך חדש: System.arraycopy(es, i + 1, es, i, size - 1 - i); החלק שנמצא מימין למיקום תחת האינדקס שצוין (i+1) מועתק למערך (es) המקורי שלנו, והוא ממוקם החל מהמיקום עצמו. (i) היכן נמצא הרכיב כדי להימחק. לפיכך, ביצענו תזוזה שמאלה ומחקנו את האלמנט שלנו.
Подробный разбор класса ArrayList [Часть 1] - 9
בואו ננסה להסיר את האלמנט באינדקס 3 מהמערך למטה:
Подробный разбор класса ArrayList [Часть 1] - 10
הבה נבחן את הגרסה השנייה של השיטה:
public boolean remove(Object o)
השיטה מסירה את הרכיב שעבר מהרשימה o, או ליתר דיוק, את האובייקט בקישור שצוין. אם רכיב קיים ברשימה, הוא מוסר וכל הרכיבים מוזזים שמאלה. אם האלמנט קיים ברשימה ומוסר בהצלחה, השיטה מחזירה true; אחרת, false. בדומה לאפשרות עם מחיקה לפי אינדקס, השיטה נקראת fastRemove(), שם בדיוק מתרחשות אותן פעולות. ההבדל הוא שהמתודה remove(Object o)מחפשת בנוסף את האובייקט הרצוי באמצעות מתודה equals()של מחלקת Object. בעת הסרה לפי ערך, הלולאה עוברת דרך כל האלמנטים של הרשימה עד שנמצאת התאמה. רק הרכיב הראשון שנמצא יימחק. נסכם: בעת מחיקת אלמנטים ממערך דינמי, לא נותרים חורים כמו במערך רגיל (התא שנמחק לא יהיה ריק). כל האלמנטים הבאים (שהיו מימין לאינדקס) מוזזים מיקום אחד שמאלה. ישנן מספר שיטות נוספות שניתן להשתמש בהן כדי להסיר אלמנטים מהרשימה בדרגות שונות. בואו נסתכל עליהם בקצרה. מנקים את האוסף שלנו:
public void clear()
לולאה פשוטה forחוזרת דרך כל האלמנטים של מערך, ומקצה ריק לכל אלמנט. אתה יכול להסיר את הרכיבים האלה מהאוסף שלנו הכלולים באוסף אחר שהועבר בצורה הבאה:
public boolean removeAll(Collection< ?> c)
אם אתה צריך להסיר כמה אלמנטים, כנראה שלא כדאי לעשות זאת בלולאה מותנית: זה נוח יותר ובטוח יותר להשתמש בשיטה removeAll(). הוא מקבל אוסף של אלמנטים שיוסרו מהרשימה. האוסף חייב להכיל אלמנטים מאותו סוג שרשימת היעד מאחסנת. אחרת זה ייזרק לפח ClassCastException. השיטה תחזיר אמת אם הרשימה שונתה כתוצאה מקריאה למתודה.
Подробный разбор класса ArrayList [Часть 1] - 11
מסיר אלמנטים שאינם שייכים לאוסף שעבר:
public boolean retainAll(Collection< ?> c)
Подробный разбор класса ArrayList [Часть 1] - 12
נניח שיש לנו אוסף:
List< String> listFirst = new ArrayList<>();
listFirst.add("White");
listFirst.add("Black");
listFirst.add("Red");
והשני:
List< String> listSecond = new ArrayList<>();
listSecond.add("Green");
listSecond.add("Red");
listSecond.add("White");
ואז אחרי listSecond.retainAll(listFirst)ב listSecondיישאר:

"White"
"Red"
מאז הוסר "ירוק", שאינו ב listFirst. אבל אחרי listSecond.removeAll(listFirst)זה זה listSecondיישאר:

"Green"
Удалorсь все элементы, которые есть в listFirst.
לא שייך לאוסף שעבר - אומר שאם יש אלמנטים שלא נמצאים באוסף שעבר, אז צריך להסיר אותם מהראשון (שעליו מיושמת השיטה). השתייכות לאוסף המועבר - בהתאם לכך, אם יש מרכיב גם באוספה הראשונה וגם בשנייה (המועברת), אזי הכפיל מהראשון מושמד.
protected void removeRange(int fromIndex, int toIndex)
מסיר מהרשימה את כל האלמנטים שנמצאים בין האינדקס שצוין מתחיל (כולל) לבין האינדקס שצוין בסוף (לא כולל). ראוי לציין שלא ניתן לקרוא לשיטה ישירות על אובייקט ArrayList. כדי להשתמש בו אתה צריך לרשת מ- AbstractList/ArrayList. השיטה משמשת גם בשיטה אחרת (subList, עליה נדון בהמשך).
public boolean removeIf(Predicate< ? super E> filter)
מסיר אלמנטים מאוסף על סמך פרדיקט נתון. הפרדיקט עצמו הוא פונקציה/אלגוריתם/תנאי מסוים שעל בסיסו יוסר אלמנט אחד או יותר התואם תנאי נתון. Predicate- ממשק פונקציונלי (מכיל רק שיטה אחת, כך שניתן להשתמש בו כלמבדה), עובד על העיקרון "קיבל פרמטר אחד - חזר בווליאני". בעיקרו של דבר, השיטה עוקפת את ההטמעה מהממשק Collectionומיישמת את ה"אסטרטגיה" הבאה: היא עוברת בלולאה דרך האלמנטים ומסמנת את אלה התואמים את ה- Predicate; לאחר מכן הוא עובר פעם נוספת כדי להסיר (ולהזיז) את האלמנטים שסומנו באיטרציה הראשונה. בואו ליישם ממשק Predicateשיחזיר אמת אם שני אובייקטים שווים:
class SamplePredicate< T> implements Predicate< T>{
  T varc1;
  public boolean test(T varc){
     if(varc1.equals(varc)){
       return true;
  }
  return false;
  }
}
במחלקה אחרת, בואו ניצור ArrayList מתוך Stringואובייקט של המחלקה שלנו שמיישם Predicate:
ArrayList< String> color_list = new ArrayList<> ();
SamplePredicate< String> filter = new SamplePredicate<> ();
varc1בוא נכתוב את הערך "לבן" למשתנה :
filter.varc1 = "White";
בואו נוסיף כמה שורות לרשימה:
color_list.add("White");
color_list.add("Black");
color_list.add("Red");
color_list.add("White");
color_list.add("Yellow");
color_list.add("White");
בוא נבצע את השיטה ברשימה removeIf, אליה נעביר את האובייקט שלנו עם התנאי:
color_list.removeIf(filter);
כתוצאה מכך, כל השורות עם הערך "לבן" יוסרו מהרשימה, מכיוון שה"פרדיקט" שלנו משווה ביניהן שוויון. רשימה סופית: [שחור, אדום, צהוב].
Подробный разбор класса ArrayList [Часть 1] - 13
החלפת אלמנטים
public E set(int index, E element)
מחליף את הרכיב במיקום שצוין indexבאחד שעבר element. האינדקס חייב להיות גם גדול מאפס וקטן מהאינדקס של האלמנט האחרון, אחרת ייגרם חריגה IndexOutOfBoundsException. לא מתרחשים עותקים של המערך הפנימי. פשוט, במקום האלמנט באינדקס שצוין, מוכנס אלמנט חדש, כלומר. להחליף את הערך.
Подробный разбор класса ArrayList [Часть 1] - 14
public void replaceAll(UnaryOperator<e> operator)
משנה את כל רכיבי האוסף (אפשרי עם תנאי). משמש בעיקר בשילוב עם למבדות או מחלקה אנונימית (אבל לשם הבהירות, בדוגמה פשוט נשתמש במחלקה שמטמעת את הממשק) המיישמת את הממשק UnaryOperatorומגדירה את השיטות שלו. בואו ליישם את הממשק:
class MyOperator< T> implements UnaryOperator< T>{
   T varc1;
   public T apply(T varc){
     return varc1;
  }
}
במחלקה אחרת, בואו ניצור ArrayList מתוך Stringואובייקט של המחלקה שלנו שמיישם UnaryOperator:
ArrayList< String> color_list = new ArrayList<> ();
MyOperator< String> operator = new MyOperator<> ();
varc1בוא נכתוב את הערך "לבן" למשתנה :
operator.varc1 = "White";
בואו נוסיף כמה שורות לרשימה:
color_list.add("White");
color_list.add("Black");
color_list.add("Red");
color_list.add("White");
color_list.add("Yellow");
color_list.add("White");
בוא נבצע שיטה ברשימה replaceAllשאליה נעביר את האובייקט שלנו operator:
color_list.replaceAll(operator);
כתוצאה מכך, כל הערכים ברשימה הוחלפו ב"לבן": [לבן, לבן, לבן, לבן, לבן, לבן]. וכך, למשל, ניתן להסיר את כל הרווחים מהמחרוזות שנמצאות באוסף:
ArrayList< String> list = new ArrayList<>(Arrays.asList("A   ", "  B  ", "C"));
list.replaceAll(String::trim);
שיטות אחרות: ניתן להמיר ArrayList למערך רגיל באמצעות השיטה:
public Object[] toArray()
אוֹ
public < T> T[] toArray(T[] a)
- כאן נקבע סוג המערך המוחזר בשיטה runtime זו תאפשר:
  1. להאיץ פעולות מסוימות;
  2. להעביר מערך כפרמטר למתודה שאינה עמוסה כדי לקבל את האוסף ישירות;
  3. שילוב קוד חדש מבוסס אוסף עם קוד מדור קודם שאינו מזהה אוספים.
החזר אובייקט העתק של המערך:
public Object clone()
שימו לב שהמתודה clone()מחזירה את סוג ה-Object, אז לאחר הקריאה אליה תצטרכו להטיל למחלקה הנדרשת. שיבוט יוצר אובייקט עצמאי חדש. בדוק את האוסף עבור נוכחות של חפץ:
public boolean contains(Object o)
בודק נוכחות של אובייקט ברשימה (באופן פנימי בשיטת equals של המחלקה Object, כלומר משווה הפניות), מחזיר אמת/לא נכון בהתאם לתוצאה. בנוסף ללולאות הרגילות, אתה יכול לעבור דרך (לגשת לכל אלמנט, כמו גם לבצע פעולה כלשהי) אוסף באמצעות:
public void forEach(Consumer< ? super E> action)
כך נוכל להציג את הרשימה שלנו:
List< Integer> numbers = new ArrayList<>(Arrays.asList(10, 20, 50, 100, -5));
numbers.forEach((number)-> System.out.println(number));
מבלי להשתמש ב-lambdas אתה צריך להשתמש במחלקה אנונימית ולעקוף את שיטת acceptהממשק Consumer:
numbers.forEach(new Consumer< Integer>() {
  @Override
   public void accept(Integer integer) {
      System.out.println(integer);
          }
});
קבל אלמנט לפי האינדקס שלו:
public E get(int index)
משמש לגישה אקראית לרכיבי אוסף. מחזירה את הרכיב הממוקם ברשימה באינדקס שצוין. אם index < 0או הוא index >=המספר המרבי של רכיבים ברשימה, ייגרם חריג IndexOutOfBoundsException. זוהי השיטה הבסיסית לאחזור אלמנט מרשימה, והזמן לאחזור אלמנט לפי אינדקס תמיד יהיה זהה, ללא קשר לגודל ה-ArrayList, מכיוון שהוא ניגש לתא מערך ספציפי. מציאת אינדקסים עבור אובייקטים שצוינו:
public int indexOf(Object o);
public int lastIndexOf(Object o);
השיטות מחזירות את האינדקס של האלמנט הראשון (כאשר האובייקט הנתון נתקל לראשונה) או המופע האחרון (כאשר האובייקט הנתון נתקל לאחרונה) ברשימה. אם האלמנט לא קיים ברשימה, המתודות יחזירו -1.
Подробный разбор класса ArrayList [Часть 1] - 16
Подробный разбор класса ArrayList [Часть 1] - 17
בדוק את האוסף עבור אלמנטים:
public boolean isEmpty();
השיטה מחזירה true אם הרשימה ריקה (מחפשת לראות אם השדה שווה size 0), אחרת false. אם הרשימה מכילה רק אלמנטים null, השיטה תחזיר false. במילים אחרות, אלמנטים null נלקחים בחשבון גם בשיטה זו. גלה את מספר האלמנטים ברשימה:
public int size();
מחזירה את מספר האלמנטים ברשימה (ערכי שדות גודל). מספר האלמנטים עשוי להיות שונה מקיבולת הרשימה (הקיבולת). קבל איטרטור לרשימה:
public Iterator< E> iterator();
מחזירה איטרטור עבור רשימה לשימוש מאוחר יותר בלולאה או בכל עיבוד אחר. האיטרטור מיישם התנהגות מהירה לכישלון. אם הוא עובר דרך האוסף ומבחין בשינויים מסוימים בו (שלא הושגו באמצעות שיטות האיטרטור), הוא זורק מיד חריגה ConcurrentModificationException. לאיטרטור יש משהו שנקרא modification count. כאשר האיטרטור חוזר על האוסף לאחר כל next/hasNext/remove, הוא בודק את המונה הזה. אם זה לא תואם למה שהאיטרטור ציפה לראות, הוא זורק חריג. לא אשקול את האיטרטורים בפירוט כאן.
public ListIterator< E> listIterator() и public ListIterator< E> listIterator(int index)
מחזירה איטרטור רשימה עבור רשימה לשימוש מאוחר יותר בלולאה או בכל עיבוד אחר. הממשק ListIteratorמרחיב את הממשק Iteratorלמעבר דו-כיווני של הרשימה ושינוי האלמנטים שלה. בגרסה העמוסה, אתה יכול להעביר את האינדקס שממנו יתחיל ה"מעבר". המדד במקרה זה מציין את האלמנט הראשון שממנו תתחיל השיטה את עבודתה next(), וכאשר השיטה נקראת, previous()המעבר יתחיל מהאלמנט שמתחת לאינדקס "עבר מדד - 1".
public Spliterator <E> spliterator()
Java 8 מציגה סוג חדש של איטרטור כריכה מאוחר ואיטרטור מהיר כישלון הנקרא איטרטור מפריד. איטרטורים מפרידים מאפשרים לך לחזור על רצף של אלמנטים, אך הם משמשים בצורה שונה. המאפיין החשוב ביותר של ממשק Spliterator הוא היכולת שלו לתמוך באיטרציה מקבילה של חלקים בודדים של רצף אלמנטים, ולכן בתכנות מקביל.
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION