JavaRush /בלוג Java /Random-HE /מחלקת מערכים והשימוש בה

מחלקת מערכים והשימוש בה

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

  • לפיכך, לאחר המעבר הראשון דרך רכיבי המערך, מובטח שהערך הגדול ביותר (167) יהיה בתא האחרון.

  • כעת נעבור שוב על כל האלמנטים של המערך, החל מהאלמנט עם index [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 in the wrong 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];
תחשוב איך היית עושה את זה באמצעות הידע על מערכים שכבר יש לך? אתה יכול, למשל, לעבור בלולאה דרך מערך numbersולכתוב את האלמנטים שלו בזה אחר זה לתוך 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 Arrays

כיתת Java מיוחדת תעזור לך לפתור בעיות טיפוסיות בעבודה עם מערכים - Arrays. לכיתה זו נוספו שיטות כדי לפתור את הבעיות הנפוצות ביותר שמתכנתי 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 האלמנטים הראשונים numbersיועתקו למערך החדש. פלט מסוף:

[167, -2, 16, 99]
אגב, אם אתה צריך להעתיק חלק ממערך, אבל לא מההתחלה, אלא "מהאמצע", 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.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));
   }
}
אנחנו מקבלים את התוצאה false. 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));
   }
}
סיכום:

true
אגב, הכיתה 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 to each other?");
       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(); בעתיד תראו יותר מפעם אחת (ותשמחו על כך) שיוצרי ג'אווה חזו הרבה מצבים אופייניים שמתכנתים נתקלים בהם בזמן העבודה, והטמיעו עבורם פתרונות מוכנים בשפה. השימוש בפתרונות הללו הוא הרבה יותר קל ונוח מאשר להמציא מחדש גלגלים, נכון? :) הקפידו לקרוא את תיעוד הכיתה Arraysבאתר אורקל . בהצלחה עם הלימודים שלך!
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION