CodeGym /בלוג Java /Random-HE /כיתת מערכים
John Squirrels
רָמָה
San Francisco

כיתת מערכים

פורסם בקבוצה
שוב שלום! :) בשיעור של היום, נדבר על שיעור Arrays בג'אווה. בשיעור האחרון הכרנו מבנה נתונים כזה שנקרא מערך. למדנו איך ליצור אותם ולמלא אותם בנתונים. ובדקנו איך הם מאוחסנים בזיכרון. היום נסתכל על כמה משימות ודוגמאות לעבודה עם מערכים שתראה לעתים קרובות בעבודה אמיתית. לדוגמה, דמיינו את המצב הזה: יש לנו מערך של 10 מספרים אקראיים.

int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
המשימה שלנו היא למיין את המערך הזה בסדר עולה: מהקטן לגדול ביותר. בסופו של דבר, זה צריך להיראות כך: [-234, -2, 16, 26, 35, 43, 92, 99, 167] איך עושים את זה? משימה זו אינה טריוויאלית. מעולם לא עשינו את זה בעבר :/ יש רעיונות? נסה לנחש. הנה פתרון אחד:
  • עברו על כל האלמנטים של המערך. השווה כל אלמנט עם הבא ([0] עם [1], [1] עם [2], [2] עם [3] וכו'). אם האלמנט הנוכחי גדול מהאלמנט הבא, אנו מחליפים אותם, ואז עוברים לאלמנט הבא. אם לא, השאירו אותם כמו שהם, והמשיכו הלאה
  • לפיכך, לאחר המעבר הראשון דרך האלמנטים, הערך הגדול ביותר (167) מובטח בתא האחרון.
  • כעת נעבור שוב על כל האלמנטים, אך הפעם נתחיל באינדקס [0] לרכיב הלפני אחרון (המספר הגדול ביותר כבר במקומו) ונבצע את אותן השוואות והחלפות. לאחר מעבר זה, בתא הלפני אחרון, יהיה לנו הערך השני בגודלו (99).
  • חזור על התהליך הזה כמה פעמים שיש לנו רכיבי מערך.
יש לנו את הרעיון. כעת נותר רק לכתוב את הקוד. זה נראה כמו זה: מחלקת מערכים והשימוש בה - 2

public class Main {

   public static void main(String[] args) {
      
       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       for (int i = numbers.length - 1; i > 0; i--) {
           for (int j = 0; j < i; j++) {
           /* Compare the elements in pairs.
             If they are not in the right order,
             then swap them */
               if (numbers[j] > numbers[j + 1]) {
                   int tmp = numbers[j];
                   numbers[j] = numbers[j + 1];
                   numbers[j + 1] = tmp;
               }
           }
       }

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

int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
המשימה שלנו היא להעתיק את תוכנו למערך אחר.

int [] numbersCopy = new int[10];
תחשוב איך היית עושה את זה באמצעות מה שאתה כבר יודע על מערכים? לדוגמה, אתה יכול לעבור על מערך המספרים בלולאה ולכתוב ברצף את האלמנטים שלו לתוך numbersCopy :

public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       int [] numbersCopy = new int[10];
      
       for (int i = 0; i < numbers.length; i++) {
          
           numbersCopy[i] = numbers[i];
       }

   }
}
ובכן, אה, הנה בעצם עשינו את זה! נראה שפתרנו את הבעיה. עם זאת, אם אתה צריך לעשות זאת לעתים קרובות, לקוד שלך יהיו חבורה של לולאות זהות. למעשה, משימות אלו (ואחרות) נפתרו מזמן על ידי יוצרי Java. אנחנו לא צריכים "להמציא את הגלגל מחדש" ולקודד את הפתרון שלנו. יש מחלקה סטטית מיוחדת ( מערכים ) כדי לעזור לך לבצע משימות נפוצות בעת עבודה עם מערכים. למחלקה זו נוספו שיטות לביצוע המשימות הנפוצות ביותר העומדות בפני מתכנתי Java. לדוגמה, משימת המיון של מערך, שניסינו לטפל בה, נפתרת בשורה אחת:

public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
      
       Arrays.sort(numbers);

       System.out.println(Arrays.toString(numbers));

   }
}
השיטה Arrays.sort() ממיינת את המערך. והאלגוריתם שלו הרבה יותר יעיל מהקוד שכתבנו. פלט מסוף: [-234, -2, 16, 26, 35, 43, 80, 92, 99, 167] הערה: כדי להמיר את המערך למחרוזת, השתמשנו בשיטה אחרת של המחלקה Arrays : Arrays.toString() . מערכים ב-Java אינם עוקפים את שיטת toString() בפני עצמם. אז, אם אתה פשוט כותב

System.out.println(numbers.toString());
ה-toString() של מחלקת Object ייקרא. עבור מערך, הפלט יהיה בערך כך: [I@4554617c לא נפרט כעת מדוע בדיוק זה הפלט. העיקר שזה ברור שזה לא מה שאנחנו צריכים. אבל Arrays.toString() עושה בדיוק מה שאנחנו רוצים. אגב, העתקה מתבצעת בקלות גם עם המחלקה Arrays :

public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       int [] numbersCopy = Arrays.copyOf(numbers, numbers.length);
       System.out.println(Arrays.toString(numbersCopy));

   }
}
אנו מעבירים לשיטת Arrays.copyOf() את המערך המקורי שלנו (ממנו אנו רוצים להעתיק ערכים) ואת אורך המערך החדש שאליו אנו מעתיקים נתונים. במקרה זה, ציינו את numbers.length כאורך, שכן רוצים להעתיק את כל המערך. אם נרצה להעתיק רק את האלמנטים הראשונים, נוכל לציין את האורך של מערך קטן יותר:

public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       int [] numbersCopy = Arrays.copyOf(numbers, 4);
       System.out.println(Arrays.toString(numbersCopy));

   }
}
כאן ציינו 4 כאורך המערך החדש. בהתאם לכך, רק 4 האלמנטים הראשונים של המספרים יועתקו למערך החדש. פלט מסוף: [167, -2, 16, 99] אגב, מערכים גם מאפשרים לך להעתיק חלק ממערך מהאמצע ולא מתחילת המערך:

public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       int [] numbersCopy = Arrays.copyOfRange(numbers, 2,6);
       System.out.println(Arrays.toString(numbersCopy));

   }
}
פלט: [16, 99, 26, 92] מספרים הועתקו למערך החדש מהמערך השני מהאלמנט השני (כולל) לאלמנט השישי (לא כולל). ייתכן שנצטרך גם להשוות בין שני מערכים. כמו בשיטת toString() , המערכים עצמם אינם עוקפים את המתודה equals() . אז אם ננסה להשוות ביניהם ככה

public class Main {

   public static void main(String[] args) {

       int[] numbers = {1, 2, 3};
       int[] numbers2 = {1, 2, 3};

       System.out.println(numbers.equals(numbers2));
   }
}
ואז נקבל שקר. הסיבה לכך היא Object.equals() , אשר משווה הפניות, ייקרא. וברור שהם שונים! אבל מה שאנחנו צריכים זה להשוות בין תוכן המערך, לא הפניות. המחלקה Arrays עוקפת את שיטת equals() כדי לגרום לה לעשות בדיוק מה שאנחנו רוצים:

public class Main {

   public static void main(String[] args) {

       int[] numbers = {1, 2, 3};
       int[] numbers2 = {1, 2, 3};

       System.out.println(Arrays.equals(numbers, numbers2));
   }
}
פלט: נכון אגב, המחלקה Arrays עובדת לא רק עם מערכים רגילים, אלא גם עם דו מימדיים:

public class Main {

   public static void main(String[] args) {

       int[][] numbers = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

       int[][] numbersCopy = Arrays.copyOf(numbers, numbers.length);

       System.out.println("Are these two-dimensional arrays equal?");
       System.out.println(Arrays.deepEquals(numbers, numbersCopy));
      
       System.out.println(Arrays.deepToString(numbersCopy));
   }
}
פלט: האם המערכים הדו-ממדיים הללו שווים? true [[1, 2, 3], [4, 5, 6], [7, 8, 9]] כפי שאתה יכול לראות, שיטת Arrays.copyOf() הצליחה להעתיק מערך דו מימדי. ולמחלקה יש שיטות מיוחדות להשוואה והצגה של מערכים דו מימדיים: deepEquals ו- deepToString() . בעתיד תראו שוב ושוב (ותשמחו על כך) שיוצרי ג'אווה ציפו להרבה מצבים בהם נתקלים מתכנתים תדיר, והטמיעו עבורם פתרונות מוכנים בשפה. השימוש בפתרונות הללו הוא הרבה יותר קל ונוח מאשר להמציא מחדש את הגלגל, נכון? :) הקפידו לקרוא את התיעוד לשיעור מערכים באתר אורקל . בהצלחה בלימודים!
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION