Arrays.deepEquals

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

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

למידע נוסף על השיטות השונות ב java.util. מערכים בכיתה, עיין במדריך המהיר שלנו.

2. מטרה

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

עכשיו, בואו לגלות פרטים נוספים על ה- deepEquals שיטה.

2.1. תחביר

נתחיל במבט על ה- חתימת שיטה:

עמוק בוליאני סטטי ציבורי שווה ערך (אובייקט [] a1, אובייקט [] a2)

מחתימת השיטה אנו מבחינים בכך אנחנו לא יכולים להשתמש deepEquals להשוות שני מערכים חד-ממדיים של סוגי נתונים פרימיטיביים. לשם כך עלינו לתייג את המערך הפרימיטיבי לעטיפה המתאימה שלו או להשתמש ב- Arrays.equals שיטה, שהעמיסה שיטות עבור מערכים פרימיטיביים.

2.2. יישום

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

לכן, עלינו לעשות זאת הימנע משימוש ב- deepEquals שיטה עם מערכים בעלי התייחסות עצמית כי זה יביא ל- a java.lang.StackOverflowError.

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

3. פלט

ה Arrays.deepEquals השיטה מחזירה:

  • נָכוֹן אם שני הפרמטרים הם אותו אובייקט (יש אותה התייחסות)
  • נָכוֹן אם שני הפרמטרים הם ריק
  • שֶׁקֶר אם רק אחד משני הפרמטרים הוא ריק
  • שֶׁקֶר אם למערכים אורכים שונים
  • נָכוֹן אם שני המערכים ריקים
  • נָכוֹן אם המערכים מכילים מספר זהה של אלמנטים וכל זוג תת רכיבים שווים עמוק
  • שֶׁקֶר במקרים אחרים

בחלק הבא נבחן כמה דוגמאות קוד.

4. דוגמאות

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

4.1. מערכים חד מימדיים

ראשית, נתחיל בדוגמה פשוטה ונשווה שני מערכים חד-ממדיים מסוג לְהִתְנַגֵד:

 אובייקט [] anArray = אובייקט חדש [] {"string1", "string2", "string3"}; אובייקט [] anotherArray = אובייקט חדש [] {"string1", "string2", "string3"}; assertTrue (Arrays.equals (anArray, anotherArray)); assertTrue (Arrays.deepEquals (anArray, anotherArray));

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

 אובייקט [] anArray = אובייקט חדש [] {"string1", null, "string3"}; אובייקט [] anotherArray = אובייקט חדש [] {"string1", null, "string3"}; assertTrue (Arrays.equals (anArray, anotherArray)); assertTrue (Arrays.deepEquals (anArray, anotherArray));

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

אבל בואו ננסה דבר נוסף ובואו נבדוק את ההתנהגות עם מערכים מקוננים:

 אובייקט [] anArray = אובייקט חדש [] {"string1", null, new String [] {"nestedString1", "nestedString2"}}; אובייקט [] anotherArray = אובייקט חדש [] {"string1", null, new String [] {"nestedString1", "nestedString2"}}; assertFalse (Arrays.equals (anArray, anotherArray)); assertTrue (Arrays.deepEquals (anArray, anotherArray));

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

4.2. מערכים רב מימדיים מסוגים פרימיטיביים

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

 int [] [] anArray = {{1, 2, 3}, {4, 5, 6, 9}, {7}}; int [] [] anotherArray = {{1, 2, 3}, {4, 5, 6, 9}, {7}}; assertFalse (Arrays.equals (anArray, anotherArray)); assertTrue (Arrays.deepEquals (anArray, anotherArray));

4.3. מערכים רב מימדיים של אובייקטים שהוגדרו על ידי המשתמש

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

נתחיל ביצירת פשוט אדם מעמד:

 אדם בכיתה {מזהה פרטי פרטי; שם מחרוזת פרטי; גיל פרטי פרטי; // constructor & getters & setters @Override בוליאני ציבורי שווה (Object obj) {if (this == obj) {return true; } אם (obj == null) {return false; } אם (! (obj instance of Person)) להחזיר שקר; אדם אדם = (אדם) אובייקט; החזר id == person.id && name.equals (person.name) && age == person.age; }}

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

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

לאחר מכן נוכל להשוות בין שני מערכים רב-ממדיים של ה- אדם מעמד:

 אדם personArray1 [] [] = {{אדם חדש (1, "ג'ון", 22), אדם חדש (2, "מייק", 23)}, {אדם חדש (3, "סטיב", 27), אדם חדש ( 4, "גארי", 28)}}; אדם personArray2 [] [] = {{אדם חדש (1, "ג'ון", 22), אדם חדש (2, "מייק", 23)}, אדם חדש (3, "סטיב", 27), אדם חדש ( 4, "גארי", 28)}}; assertFalse (Arrays.equals (personArray1, personArray2)); assertTrue (Arrays.deepEquals (personArray1, personArray2));

כתוצאה מהשוואה רקורטיבית של תתי-המשנה, לשתי השיטות שוב תוצאות שונות.

לבסוף, ראוי להזכיר כי ה-Objects.deepEquals השיטה מבצעת את Arrays.deepEquals שיטה פנימית כשזה נקרא עם שניים לְהִתְנַגֵד מערכים:

 assertTrue (Objects.deepEquals (personArray1, personArray2));

5. מסקנה

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

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