פעולות מערך ב- Java

1. סקירה כללית

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

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

2. מערכים ושיעורי עוזר

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

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

מסיבה זו, במרבית פעולותינו נשתמש בשיעורי עוזר ובשיטות שיעזרו לנו: מערכים מחלקה המסופקת על ידי Java ו- Apache's ArrayUtils אחד.

כדי לכלול את האחרון בפרויקט שלנו, נצטרך להוסיף את התלות של Apache Commons:

 org.apache.commons commons-lang3 3.8.1 

אנו יכולים לבדוק את הגרסה האחרונה של חפץ זה במרכז מייבן.

3. קבל את האלמנט הראשון והאחרון של מערך

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

נתחיל בהכרזה וביצוע אתחול של int מערך שישמש בכל הדוגמאות שלנו (אלא אם כן אנו מציינים אחרת):

int [] array = int int [] {3, 5, 2, 5, 14, 4};

בידיעה שהפריט הראשון במערך משויך לערך האינדקס 0 ושיש לו a אורך המאפיין שנוכל להשתמש בו, אז פשוט להבין איך נוכל להשיג את שני האלמנטים האלה:

int firstItem = מערך [0]; int lastItem = מערך [מערך.אורך - 1];

4. קבל ערך אקראי ממערך

באמצעות java.util.Random אנו יכולים בקלות להשיג כל ערך מהמערך שלנו:

int anyValue = array [חדש אקראי (). nextInt (array.length)];

5. הוסף פריט חדש למערך

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

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

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

int [] newArray = Arrays.copyOf (מערך, מערך.אורך + 1); newArray [newArray.length - 1] = newItem;

אופציונלי, אם ArrayUtils בכיתה נגיש בפרויקט שלנו, אנו יכולים להשתמש בו להוסיף שיטה (או שלה הוסף הכל אלטרנטיבה) להשגת מטרתנו בהצהרה שורה אחת:

int [] newArray = ArrayUtils.add (מערך, newItem);

כפי שאנו יכולים לדמיין, שיטה זו אינה משנה את המקור מַעֲרָך לְהִתְנַגֵד; עלינו להקצות את הפלט שלו למשתנה חדש.

6. הכנס ערך בין שני ערכים

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

אפאצ'י ראה בכך תרחיש אופייני והטמיע שיטה בתוכו ArrayUtils בכיתה לפשט את הפתרון:

int [] largeArray = ArrayUtils.insert (2, array, 77);

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

הטיעון האחרון הוא טיעון משתנה (ע.ק. varargכך נוכל להוסיף מספר כלשהו של פריטים במערך.

7. השווה בין שני מערכים

למרות שמערכים הם לְהִתְנַגֵדs ולכן מספקים שווים בשיטה, הם משתמשים ביישום ברירת המחדל שלה, ומסתמכים רק על שוויון התייחסות.

אנחנו יכולים בכל מקרה להפעיל את java.util. מערכיםשווים שיטה לבדוק אם שני אובייקטים של מערך מכילים את אותם ערכים:

areEqual בוליאני = Arrays.equals (array1, array2);

הערה: שיטה זו אינה יעילה עבור מערכים משוננים. השיטה המתאימה לאימות שוויון של מבנים רב מימדיים היא Arrays.deepEquals אחד.

8. בדוק אם מערך ריק

זו מטלה לא מסובכת תוך התחשבות שנוכל להשתמש ב אורך תכונה של מערכים:

isEmpty בוליאני = מערך == null || array.length == 0;

יתר על כן, יש לנו גם שיטה בטוחה ללא null ArrayUtils מעמד עוזר בו נוכל להשתמש:

isEmpty בוליאני = ArrayUtils.isEmpty (מערך);

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

// אלה מערכים ריקים שלם [] מערך 1 = {}; מספר שלם [] מערך 2 = null; מספר שלם [] מערך 3 = מספר שלם חדש [0]; // כל אלה לא ייחשבו ריקים כשלם [] מערך 3 = {null, null, null}; מספר שלם [] [] מערך 4 = {{}, {}, {}}; מספר שלם [] מערך 5 = מספר שלם חדש [3];

9. כיצד לדשדש את אלמנטים של מערך

על מנת לדשדש את הפריטים במערך, אנו יכולים להשתמש ב- ArrayUtilהתכונה:

ArrayUtils.shuffle (מערך);

זה בָּטֵל שיטה ופועל לפי הערכים בפועל של המערך.

10. קופסא ומערכי Unbox

לעתים קרובות אנו נתקלים בשיטות התומכות בלבד לְהִתְנַגֵדמערכים מבוססים.

שוב ה ArrayUtils כיתת עוזר שימושית להשיג גרסה ממוסגרת של המערך הפרימיטיבי שלנו:

מספר שלם [] רשימה = ArrayUtils.toObject (מערך);

הפעולה ההפוכה אפשרית גם:

מספר שלם [] objectArray = {3, 5, 2, 5, 14, 4}; int [] array = ArrayUtils.toPrimitive (objectArray);

11. הסר כפילויות ממערך

הדרך הקלה ביותר להסיר כפילויות היא על ידי המרת המערך ל- מַעֲרֶכֶת יישום.

כפי שאולי נדע, אוסףהם משתמשים בגנריות ולכן אינם תומכים בסוגים פרימיטיביים.

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

// תיבת שלם [] רשימה = ArrayUtils.toObject (מערך); // הסר כפילויות Set set = חדש HashSet (Arrays.asList (רשימה)); // צור מערך ובטל את תיבת החזרת ArrayUtils.toPrimitive (set.toArray (מספר שלם חדש [set.size ()]));

הערה: אנו יכולים להשתמש בטכניקות אחרות להמרה בין מערך ל- a מַעֲרֶכֶת גם חפץ.

כמו כן, אם עלינו לשמור על סדר האלמנטים שלנו, עלינו להשתמש בשונה מַעֲרֶכֶת יישום, כגון א LinkedHashSet.

12. כיצד להדפיס מערך

אותו דבר כמו עם ה- שווים השיטה, המערך toString הפונקציה משתמשת ביישום ברירת המחדל שמספק ה- לְהִתְנַגֵד בכיתה, וזה לא מאוד שימושי.

שניהם מערכים ו ArrayUtils כיתות נשלחות עם היישומים שלהן כדי להמיר את מבני הנתונים לקריאים חוּט.

מלבד הפורמט המעט שונה בו הם משתמשים, ההבחנה החשובה ביותר היא האופן שבו הם מתייחסים לאובייקטים רב ממדיים.

המחלקה של Java Util מספקת שתי שיטות סטטיות בהן אנו יכולים להשתמש:

  • toString: לא עובד טוב עם מערכים משוננים
  • deepToString: תומך בכל לְהִתְנַגֵדמערכים מבוססים אך אינו מתקבל עם טיעוני מערך פרימיטיביים

מצד שני, היישום של אפאצ'י מציע יחיד toString שיטה שעובדת נכון בכל מקרה:

מחרוזת arrayAsString = ArrayUtils.toString (מערך);

13. מיפג מערך לסוג אחר

לעתים קרובות שימושי ליישם פעולות על כל פריטי המערך, ואולי להמיר אותם לסוג אחר של אובייקט.

עם מטרה זו בראש ננסה ליצור שיטת עוזר גמישה באמצעות Generics:

U [] mapObjectArray (T [] מערך, פונקציית פונקציה, Class targetClazz) {U [] newArray = (U []) Array.newInstance (targetClazz, array.length); עבור (int i = 0; i <array.length; i ++) {newArray [i] = function.apply (array [i]); } להחזיר newArray; }

אם איננו משתמשים ב- Java 8 בפרויקט שלנו, אנו יכולים להשליך את ה- פוּנקצִיָה ויכוח, וליצור שיטה לכל מיפוי שעלינו לבצע.

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

@ מבחן ציבורי בטל כאשר MapArrayMultiplyingValues_thenReturnMultipliedArray () {Integer [] multiplierExpectedArray = Integer [Integer] חדש [] {6, 10, 4, 10, 28, 8}; מספר שלם [] פלט = MyHelperClass.mapObjectArray (מערך, ערך -> ערך * 2, Integer.class); assertThat (פלט) .containsExactly (multiplierExpectedArray); } @Test ציבורי בטל כאשר MapDividingObjectArray_thenReturnMultipliedArray () {Double [] multiplierExpectedArray = new Double [] {1.5, 2.5, 1.0, 2.5, 7.0, 2.0}; פעמיים [] פלט = MyHelperClass.mapObjectArray (מערך, ערך -> ערך / 2.0, Double.class); assertThat (פלט) .containsExactly (multiplierExpectedArray); }

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

כחלופה, אנו יכולים לפנות לזרמים של Java 8 כדי לבצע את המיפוי עבורנו.

נצטרך להפוך את המערך ל- זרם שֶׁל לְהִתְנַגֵדהראשון. אנחנו יכולים לעשות זאת עם Arrays.stream שיטה.

למשל, אם אנחנו רוצים למפות את שלנו int ערכים למנהג חוּט ייצוג, אנו מיישמים זאת:

String [] stringArray = Arrays.stream (array) .mapToObj (value -> String.format ("Value:% s", value)) .toArray (String [] :: new);

14. סנן ערכים במערך

סינון ערכים מאוסף הוא משימה שכיחה שנצטרך לבצע ביותר מפעם אחת.

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

תאר לעצמך שאנחנו רוצים להסיר את כל המספרים המוזרים ממערך:

int [] evenArray = Arrays.stream (array) .filter (value -> value% 2 == 0) .toArray ();

15. פעולות מערך נפוצות אחרות

יש, כמובן, שפע פעולות מערך אחרות שנצטרך לבצע.

מלבד אלה המוצגים במדריך זה, סקרנו בהרחבה פעולות אחרות בפוסטים הייעודיים:

  • בדוק אם מערך Java מכיל ערך
  • כיצד להעתיק מערך ב- Java
  • הסרת האלמנט הראשון של מערך
  • מציאת המינימום והמקס במערך עם ג'אווה
  • מצא סכום וממוצע במערך Java
  • כיצד להפוך מערך בג'אווה
  • הצטרף ולפצל מערכים ואוספים בג'אווה
  • שילוב של סוגי אוספים שונים בג'אווה
  • מצא את כל זוגות המספרים במערך שמסתכם בסכום נתון
  • מיון בג'אווה
  • מחשבון תדרי מילים יעיל בג'אווה
  • מיון הכנסה ב- Java

16. מסקנה

מערכים הם אחד מתפקידי הליבה של ג'אווה, ולכן חשוב מאוד להבין כיצד הם עובדים ולדעת מה אנו יכולים ולא יכולים לעשות איתם.

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

כמו תמיד, קוד המקור המלא של דוגמאות העבודה זמין בתיקון Github שלנו.


$config[zx-auto] not found$config[zx-overlay] not found