השוואת מערכים בג'אווה

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

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

2. השוואת מערכים

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

  • לאובייקטים יש אזכורים וערכים
  • שתי הפניות שוות צריכות להצביע על אותו ערך
  • שני ערכים שונים צריכים להיות בעלי אזכורים שונים
  • לשני ערכים שווים אין בהכרח את אותם הפניות
  • ערכים פרימיטיביים מקבלים השוואה רק לערך
  • מילולי מחרוזות מקבלים השוואה רק לערך

2.1. השוואת הפניות לאובייקטים

אם יש לנו שני אזכורים שמפנים לאותו מערך, אנחנו תמיד צריכים לקבל תוצאה נָכוֹן בהשוואה שווה ל- == מַפעִיל.

בואו נסתכל על דוגמה:

מחרוזת [] planes1 = מחרוזת חדשה [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; מחרוזת [] planes2 = planes1;

ראשית, יצרנו מערך של דגמי מטוס אליהם הפניה מטוסים 1. לאחר מכן אנו יוצרים מטוסים 2, אילו הפניות מטוסים 1. על ידי כך אנו יצירת שתי אזכוריםלאותו מערך בזיכרון. לכן, ה “מטוסים 1 == מטוסים 2” הביטוי יחזור נָכוֹן.

עבור מערכים, ה- שווים() השיטה זהה למפעיל ==. כך, planes1.equals (planes2) החזרות נָכוֹן מכיוון ששתי הפניות מתייחסות לאותו אובייקט. באופן כללי, array1.eqauls (array2) יחזור נָכוֹן אם ורק אם הביטוי מערך 1 == מערך 2 ″ החזרות נָכוֹן.

בואו נקבע אם שתי ההפניות זהות:

assertThat (planes1) .isSameAs (planes2);

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

planes2 [0] = "747";

כדי לראות סוף סוף את זה עובד, בואו נקבע את הטענות שלנו:

assertThat (planes1) .isSameAs (planes2); assertThat (planes2 [0]). isEqualTo ("747"); assertThat (planes1 [0]). isEqualTo ("747");

במבחן יחידה זה הצלחנו להשוות שני מערכים בהתייחס.

עם זאת, רק הוכחנו זאת הפניה אחת, לאחר שהוקצה לערך של אחר, תתייחס לאותו ערך.

כעת ניצור שני מערכים שונים עם אותם ערכים:

מחרוזת [] planes1 = מחרוזת חדשה [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; מחרוזת [] planes2 = מחרוזת חדשה [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"};

מכיוון שהם אובייקטים שונים, אנו יודעים בוודאות שהם אינם זהים. אנו יכולים, אם כן, להשוות ביניהם:

assertThat (planes1) .isNotSameAs (planes2);

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

2.2. השוואת אורכי מערך

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

בואו ניצור שני מערכים:

מחרוזת סופית [] planes1 = מחרוזת חדשה [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; מספר שלם סופי [] כמויות = מספר שלם חדש [] {10, 12, 34, 45, 12, 43, 5, 2};

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

assertThat (planes1) .hasSize (8); assertThat (כמויות) .hasSize (8);

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

2.3. השוואת מערכים עם Arrays.equals

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

בואו ניצור שני מערכים שונים עם אותו הדבר חוּט מילוליות באותו סדר בדיוק:

מחרוזת [] planes1 = מחרוזת חדשה [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; מחרוזת [] planes2 = מחרוזת חדשה [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"};

ועכשיו, בואו ונטען שהם שווים:

assertThat (Arrays.equals (planes1, planes2)). isTrue ();

אם נשנה את סדר הערכים של המערך השני:

מחרוזת [] planes1 = מחרוזת חדשה [] {"A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332"}; מחרוזת [] planes2 = מחרוזת חדשה [] {"B738", "A320", "A321", "A319", "B77W", "B737", "A333", "A332"}; 

נקבל תוצאה אחרת:

assertThat (Arrays.equals (planes1, planes2)). isFalse ();

2.4. השוואת מערכים עם Arrays.deepEquals

משתמש ב == האופרטור קל אם אנו משתמשים בסוגים פשוטים ב- Java. אלה יכולים להיות סוגים פרימיטיביים או חוּט מילוליות. השוואה בין מערכים של לְהִתְנַגֵדזה יכול להיות מסובך יותר. הסיבה מאחורי זה מוסברת במלואה שלנו Arrays.deepEquals מאמר. בואו נראה דוגמא.

ראשית, נתחיל עם מָטוֹס מעמד:

מטוס בכיתה ציבורית {פרטי סופי שם מחרוזת; דגם מחרוזת סופי פרטי; // גטרים וקובעים}

ובואו ליישם את hashCode ו שווים שיטות:

@ עקוף בוליאני ציבורי שווה (אובייקט o) אם (זה == o) יחזיר נכון; אם (o == null @ חקירה ציבורית int hashCode () {להחזיר Objects.hash (שם, מודל);}

שנית, בואו ניצור את המערכים הבאים של שני אלמנטים:

מטוס [] [] planes1 = מטוס חדש [] [] {מטוס חדש [] {מטוס חדש ("מטוס 1", "A320")}, מטוס חדש [] {מטוס חדש ("מטוס 2", "B738") }}; מטוס [] [] planes2 = מטוס חדש [] [] {מטוס חדש [] {מטוס חדש ("מטוס 1", "A320")}, מטוס חדש [] {מטוס חדש ("מטוס 2", "B738") }}; 

בואו נראה עכשיו אם הם מערכים אמיתיים, שווים מאוד:

assertThat (Arrays.deepEquals (planes1, planes2)). isTrue ();

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

מטוס [] [] planes1 = מטוס חדש [] [] {מטוס חדש [] {מטוס חדש ("מטוס 1", "A320")}, מטוס חדש [] {מטוס חדש ("מטוס 2", "B738") }}; מטוס [] [] planes2 = מטוס חדש [] [] {מטוס חדש [] {מטוס חדש ("מטוס 2", "B738")}, מטוס חדש [] {מטוס חדש ("מטוס 1", "A320") }};

לבסוף, בואו לבדוק אם הם אכן לא שווים יותר:

assertThat (Arrays.deepEquals (planes1, planes2)). isFalse ();

2.5. השוואת מערכים עם סדרי אלמנטים שונים

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

Comparator planeComparator = (o1, o2) -> {if (o1.getName (). שווה ל- (o2.getName ())) {return o2.getModel (). CompareTo (o1.getModel ()); } להחזיר o2.getName (). CompareTo (o1.getName ()); };

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

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

Arrays.sort (planes1 [0], planeComparator); Arrays.sort (planes2 [0], planeComparator);

ולסיום, בואו לבדוק אותם:

assertThat (Arrays.deepEquals (planes1, planes2)). isTrue ();

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

3. מסקנה

במדריך זה ראינו דרכים שונות להשוואת מערכים. שנית, ראינו את ההבדל בין השוואת אזכורים וערכים. בנוסף, בדקנו כיצד אנו יכולים להשוות מערכים עמוקים. לבסוף ראינו את ההבדל בין השוואה רגילה להשוואה עמוקה באמצעות שווים ו deepEquals, בהתאמה.

כמו תמיד, קוד המקור המלא של הדוגמאות זמין ב- GitHub.