Menu

Java ArrayList: יצירה, הוספה, הסרה, לולאות ומיון

איך משתמשים ב-ArrayList של Java, הרשימה שמשנה את גודלה ומחליפה מערך רגיל: add, get, remove, size, לולאות ומיון.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

רשימה שמשנה את הגודל שלה בעצמה

למערך רגיל ב-Java יש אורך קבוע: החלטתם על עשרה תאים, ויש לכם עשרה תאים לתמיד. ArrayList היא החלופה הגמישה מ-java.util: היא גדלה כשמוסיפים ומתכווצת כשמסירים, ומגיעה עם מתודות נוחות לכל מה שעושים בפועל עם רשימה.

שימו לב לטיפוס בסוגריים המשולשים, List<String>, שאומר לקומפיילר שהרשימה מחזיקה ערכי String. ה-<> (ה-"diamond") בצד ההשמה מאפשר ל-Java להסיק את אותו טיפוס בלי לחזור עליו. ושימו לב גם שמייבאים את java.util.ArrayList; היא לא זמינה כברירת מחדל.

מצהירים כ-List, יוצרים כ-ArrayList

כמעט תמיד תראו את המשתנה מוגדר כממשק List ולא כ-ArrayList הקונקרטית:

List<String> names = new ArrayList<>();

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

הוספה, קריאה ועדכון

  • add(value) מוסיפה לסוף.
  • add(index, value) מכניסה במיקום מסוים ומזיזה את האיברים שאחריו מקום אחד קדימה.
  • get(index) קוראת את האיבר במיקום מסוים (החל מאפס).
  • set(index, value) דורסת איבר קיים.

האינדקסים מתחילים מאפס, ו-get על אינדקס מחוץ לטווח זורקת IndexOutOfBoundsException.

הסרת איברים

יש מלכודת קלאסית כשהרשימה מחזיקה Integer. remove(int) היא "הסרה לפי אינדקס" ו-remove(Object) היא "הסרה לפי ערך", ולכן:

List<Integer> nums = new ArrayList<>(List.of(10, 20, 30));
nums.remove(1);                      // מסיר את אינדקס 1 -> הערך 20
nums.remove(Integer.valueOf(20));    // מסיר את הערך 20

עטפו את הערך ב-Integer.valueOf(...) כשהכוונה היא "הסר את הערך הזה" ולא "הסר את האינדקס הזה".

גודל, בדיקת הכלה וחיפוש אינדקס

List.of(...) בונה רשימה בלתי ניתנת לשינוי במהירות; העברה שלה לבנאי של ArrayList נותנת עותק שאפשר לשנות, שמאותחל עם הערכים האלה.

מעבר בלולאה על ArrayList

הלולאה הנקייה ביותר היא ה-for המשופר (לולאת for-each):

כשצריך גם את האינדקס, השתמשו בלולאה עם מונה, עם size() ו-get(i):

כלל אחד: אל תוסיפו ואל תסירו איברים מרשימה בזמן שלולאת for-each עוברת עליה, זה זורק ConcurrentModificationException. כדי למחוק בבטחה איברים שעונים לתנאי, השתמשו ב-removeIf:

מיון

Collections.sort ממיינת רשימה במקום לפי הסדר הטבעי (אלפביתי למחרוזות, מספרי למספרים):

לסדר מותאם אישית, העבירו Comparator ל-list.sort(...), למשל names.sort(Comparator.comparingInt(String::length)) כדי למיין לפי אורך.

ArrayList מחזיקה אובייקטים, לא פרימיטיביים

אי אפשר לכתוב ArrayList<int>. Generics עובדים רק עם טיפוסי אובייקט, אז השתמשו במחלקות העוטפות Integer, Double, Boolean וכן הלאה:

ה-autoboxing של Java ממיר בין int ל-Integer בשבילכם, כך שהקוד נקרא בטבעיות. רק זכרו שהרשימה עצמה שומרת אובייקטי Integer.

הבא בתור: HashMap

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

שאלות נפוצות

איך יוצרים ArrayList ב-Java?

מצהירים עליה עם טיפוס האיברים בסוגריים משולשים וקוראים לבנאי: ArrayList<String> names = new ArrayList<>();. ה-<> בצד ההשמה (ה-diamond) מאפשר ל-Java להסיק את הטיפוס. בדרך כלל מגדירים את המשתנה כממשק List: List<String> names = new ArrayList<>();.

מה ההבדל בין מערך ל-ArrayList ב-Java?

למערך רגיל יש אורך קבוע שנקבע ביצירתו, והוא יכול להכיל טיפוסים פרימיטיביים כמו int. ArrayList גדלה ומתכווצת אוטומטית כשמוסיפים ומסירים איברים, מחזיקה רק אובייקטים (כך ש-int הופך ל-Integer), ומגיעה עם מתודות כמו add, remove, contains ו-size. השתמשו במערך לנתונים פרימיטיביים בגודל קבוע; השתמשו ב-ArrayList כשהגודל משתנה.

איך מסירים איבר מ-ArrayList?

קוראים ל-remove(index) כדי להסיר לפי מיקום, או ל-remove(object) כדי להסיר את האיבר התואם הראשון. היזהרו עם רשימות של Integer: list.remove(2) מסירה את האינדקס 2, ואילו list.remove(Integer.valueOf(2)) מסירה את הערך 2. כדי להסיר תוך כדי לולאה, השתמשו ב-remove() של Iterator או ב-removeIf(...) כדי להימנע מ-ConcurrentModificationException.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל