Menu

מערכים ב-Java: הצהרה, אתחול, גישה ולולאות

איך מערכים עובדים ב-Java: אורך קבוע, הצהרה ואתחול, אינדקסים, length, לולאות, מערכים רב-ממדיים ומחלקת העזר Arrays.

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

מערך הוא רשימה בגודל קבוע

מערך ב-Java מחזיק מספר קבוע של ערכים מאותו טיפוס, מסודרים לפי הסדר ונגישים לפי מיקום. "קבוע" היא מילת המפתח: אחרי שיוצרים מערך, האורך שלו לא משתנה לעולם. וגם "אותו טיפוס": int[] מחזיק רק ערכי int, ו-String[] מחזיק רק מחרוזות. הנוקשות הזו היא המחיר של מערכים מהירים וחסכוניים בזיכרון.

מצהירים על טיפוס מערך על ידי הוספת [] אחרי טיפוס האיברים, ואז משימים ליטרל או מקצים מערך עם new:

הסוגריים יכולים לבוא אחרי הטיפוס (int[] scores) או אחרי השם (int scores[]). שתי הצורות מתקמפלות, אבל int[] scores הוא הסגנון המקובל ב-Java: שימו את ה-[] ליד הטיפוס, שם הוא שייך.

יצירת מערך עם new

כשעוד לא יודעים את הערכים אבל כן יודעים את הגודל, השתמשו ב-new. זה מקצה את התאים וממלא אותם בערך ברירת המחדל של הטיפוס:

ערכי ברירת המחדל הם לא זבל אקראי: Java מאתחלת כל איבר לאפס. טיפוסים מספריים מתחילים ב-0 (או 0.0), boolean מתחיל ב-false, וטיפוסי הפניה כמו String מתחילים ב-null. כדאי לזכור את ה-null הזה: String[] שהוקצה עכשיו מלא ב-null, וקריאה למתודה על אחד מהם זורקת NullPointerException.

האינדקסים מתחילים מאפס

קוראים וכותבים איברים לפי אינדקס, וסופרים מ-0. האינדקס החוקי האחרון הוא תמיד length - 1:

בניגוד למערכים בחלק משפות הסקריפט, חריגה מהטווח לא מחזירה בשקט null או undefined: היא זורקת חריגה. נסו לקרוא אינדקס שלא קיים:

התוכנית הזו קורסת עם:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3

זו אחת השגיאות הנפוצות ביותר אצל מתחילים. התיקון הוא כמעט תמיד טעות של אחד בתנאי של לולאה: שימוש ב-<= במקום שבו התכוונתם ל-<.

length הוא שדה, לא מתודה

כל מערך נושא את הגודל שלו בשדה length. שימו לב: בלי סוגריים.

הנה מלכודת שתופסת את כולם לפחות פעם אחת: מערכים משתמשים ב-.length (שדה), אבל String משתמש ב-.length() (מתודה). כתיבת nums.length() על מערך היא שגיאת קומפילציה, וגם כתיבת text.length על מחרוזת. אותה מילה, כללים שונים: בגרסה של המערך אין סוגריים.

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

את לולאת for-each הכרתם בעמוד הקודם, והיא הדרך הנקייה ביותר לקרוא כל איבר כשלא צריך את האינדקס:

כשצריך את האינדקס, כדי להדפיס מספרי מיקום, לשנות איברים במקום או לעבור מהסוף להתחלה, השתמשו בלולאת for הקלאסית עם אינדקס ועם length כגבול:

התנאי הוא i < names.length, לא <=. שימוש ב-<= רץ צעד אחד יותר מדי וזורק את החריגה של גישה מחוץ לטווח שראינו בסעיף הקודם. כלל מהיר: for-each כשרק קוראים ערכים, ו-for עם אינדקס כשצריך את המיקום או רוצים לכתוב חזרה למערך.

מערכים רב-ממדיים

מערך דו-ממדי הוא בעצם מערך של מערכים: חשבו עליו כעל טבלה של שורות ועמודות. מוסיפים זוג סוגריים שני:

grid[row][column] בוחר תא יחיד. מכיוון שכל שורה היא מערך נפרד, grid.length הוא מספר השורות ו-grid[0].length הוא מספר העמודות בשורה הראשונה. השורות אפילו לא חייבות להיות באותו אורך (זה נקרא jagged array), אבל רוב הטבלאות מלבניות.

מחלקת העזר Arrays

למערכים עצמם כמעט אין מתודות: אי אפשר למיין או להדפיס מערך ישירות בצורה שימושית. Java מספקת את מחלקת העזר java.util.Arrays, מלאה במתודות סטטיות בדיוק בשביל זה:

כמה דברים שכדאי להישען עליהם. Arrays.toString(arr) היא הדרך הנכונה להדפיס מערך: הדפסה ישירה נותנת מחרוזת חסרת תועלת כמו [I@1b6d3586. Arrays.sort ממיינת במקום. Arrays.copyOf היא הדרך "לשנות גודל": היא מחזירה מערך חדש באורך שביקשתם, ומשלימה בערכי ברירת מחדל (שני התאים הנוספים בדוגמה הם 0). ו-Arrays.binarySearch עובדת נכון רק על מערך שכבר ממוין.

מערכים מול ArrayList

השתמשו במערך רגיל כשהגודל ידוע מראש ולא ישתנה: קבוצה קבועה של ימי השבוע, לוח משחק, נתוני פיקסלים. מערכים מהירים וקלים, אבל האורך הקבוע שלהם הוא מגבלה אמיתית: אי אפשר להוסיף איבר שביעי למערך באורך 6 בלי לבנות מערך חדש לגמרי.

ברגע שצריך להוסיף ולהסיר פריטים בחופשיות, מערך הופך למסורבל. בשביל זה יש ArrayList: רשימה שמשנה גודל וגדלה, ומטפלת בהעתקה בשבילכם.

הבא בתור: ArrayList

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

שאלות נפוצות

איך מצהירים על מערך ומאתחלים אותו ב-Java?

מצהירים על הטיפוס עם סוגריים מרובעים ומשימים ליטרל: int[] nums = {1, 2, 3};. כדי ליצור מערך ריק בגודל קבוע, השתמשו ב-new: int[] nums = new int[5];. זה נותן 5 תאים, כל אחד מלא בערך ברירת המחדל (0 עבור int, null עבור אובייקטים).

איך מקבלים את האורך של מערך ב-Java?

השתמשו בשדה length (בלי סוגריים): nums.length. זה שדה, לא מתודה, ולכן nums.length() היא שגיאת קומפילציה. שימו לב ש-String משתמש ב-.length() עם סוגריים, אבל מערכים משתמשים ב-.length בלי: בלבול קלאסי.

האם מערך ב-Java יכול לשנות גודל אחרי שנוצר?

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

מה זה ArrayIndexOutOfBoundsException ב-Java?

זו שגיאת זמן הריצה שמקבלים כשניגשים לאינדקס שלא קיים: קטן מ-0 או >= array.length. בניגוד לשפות מסוימות, Java לא מחזירה ערך ברירת מחדל או null על גישה מחוץ לטווח; היא זורקת חריגה. אינדקסים חוקיים תמיד נעים מ-0 עד length - 1.

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

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

להתחיל