השוואת שני HashMaps בג'אווה
1. סקירה כללית
במדריך זה, אנו הולכים לבחון דרכים שונות להשוות בין שתיים HashMaps בג'אווה.
נדון בכמה דרכים לבדוק אם שתיים HashMaps דומים. נשתמש גם ב- Java 8 Stream API וב- Guava כדי לקבל את ההבדלים המפורטים בין שונים HashMaps.
2. שימוש Map.equals ()
ראשית, נשתמש Map.equals () כדי לבדוק אם שניים HashMaps יש אותם ערכים:
@ מבחן ציבורי בטל כאשרCompareTwoHashMapsUsingEquals_thenSuccess () {Map asiaCapital1 = HashMap חדש (); asiaCapital1.put ("יפן", "טוקיו"); asiaCapital1.put ("דרום קוריאה", "סיאול"); מפה asiaCapital2 = HashMap חדש (); asiaCapital2.put ("דרום קוריאה", "סיאול"); asiaCapital2.put ("יפן", "טוקיו"); מפה asiaCapital3 = HashMap חדש (); asiaCapital3.put ("יפן", "טוקיו"); asiaCapital3.put ("סין", "בייג'ינג"); assertTrue (asiaCapital1.equals (asiaCapital2)); assertFalse (asiaCapital1.equals (asiaCapital3)); }
הנה, אנחנו יוצרים שלושה מפת גיבוב אובייקטים והוספת ערכים. ואז אנחנו משתמשים Map.equals () כדי לבדוק אם שניים HashMaps יש אותם ערכים.
הדרך ש Map.equals () עובד הוא על ידי השוואת מקשים וערכים באמצעות Object.equals () שיטה. זה אומר שזה עובד רק כאשר מיישמים אובייקטים מרכזיים וגם ערכיים שווים() כמו שצריך.
לדוגמה, Map.equals () לא עובד כאשר סוג הערך הוא מערך, כמו של מערך שווים() השיטה משווה בין זהות ולא תוכן המערך:
@ מבחן ציבורי בטל כאשרCompareTwoHashMapsWithArrayValuesUsingEquals_thenFail () {Map asiaCity1 = HashMap חדש (); asiaCity1.put ("יפן", מחרוזת חדשה [] {"טוקיו", "אוסקה"}); asiaCity1.put ("דרום קוריאה", מחרוזת חדשה [] {"סיאול", "בוסאן"}); מפה asiaCity2 = HashMap חדש (); asiaCity2.put ("דרום קוריאה", מחרוזת חדשה [] {"סיאול", "בוסאן"}); asiaCity2.put ("יפן", מחרוזת חדשה [] {"טוקיו", "אוסקה"}); assertFalse (asiaCity1.equals (asiaCity2)); }
3. שימוש בג'אווה זרם ממשק API
אנו יכולים גם ליישם את השיטה שלנו להשוואה HashMaps באמצעות Java 8 זרם ממשק API:
בוליאנים פרטיים areEqual (מפה ראשונה, מפה שנייה) {if (first.size ()! = second.size ()) {return false; } תחזור first.entrySet (). stream () .allMatch (e -> e.getValue (). שווה (second.get (e.getKey ()))); }
למען הפשטות, יישמנו את ה- שווים() שיטה שבה אנו יכולים להשתמש כעת כדי להשוות מפת גיבוב חפצים:
@Test הציבור בטל כאשרCompareTwoHashMapsUsingStreamAPI_thenSuccess () {assertTrue (areEqual (asiaCapital1, asiaCapital2)); assertFalse (areEqual (asiaCapital1, asiaCapital3)); }
אבל אנחנו יכולים גם להתאים אישית את השיטה שלנו areEqualWithArrayValue () לטפל בערכי מערך באמצעות Arrays.equals () להשוואה בין שני מערכים:
הם בוליאניים פרטיים areEqualWithArrayValue (מפה ראשונה, מפה שנייה) {if (first.size ()! = second.size ()) {return false; } חזור first.entrySet (). stream () .allMatch (e -> Arrays.equals (e.getValue (), second.get (e.getKey ()))); }
בניגוד Map.equals (), השיטה שלנו תשווה בהצלחה HashMaps עם ערכי מערך:
@Test הציבור בטל כאשרCompareTwoHashMapsWithArrayValuesUsingStreamAPI_thenSuccess () {assertTrue (areEqualWithArrayValue (asiaCity1, asiaCity2)); assertFalse (areEqualWithArrayValue (asiaCity1, asiaCity3)); }
4. השוואה מפת גיבוב מפתחות וערכים
לאחר מכן, בואו נראה כיצד להשוות בין שניים מפת גיבוב המקשים והערכים התואמים שלהם.
4.1. משווים מפת גיבוב מפתחות
ראשית, אנו יכולים לבדוק אם שניים HashMaps יש אותם מקשים רק על ידי השוואת המקשים שלהם סט מפתחות():
@Test הציבור בטל כאשרCompareTwoHashMapKeys_thenSuccess () {assertTrue (asiaCapital1.keySet (). שווה (asiaCapital2.keySet ())); assertFalse (asiaCapital1.keySet (). שווה (asiaCapital3.keySet ())); }
4.2. משווים מפת גיבוב ערכים
לאחר מכן נראה כיצד ניתן להשוות מפת גיבוב ערכים אחד אחד.
אנו מיישמים שיטה פשוטה לבדוק אילו מקשים הם בעלי אותו ערך בשניהם HashMaps באמצעות זרם ממשק API:
מפה פרטית areEqualKeyValues (מפה ראשונה, מפה שנייה) {חזור first.entrySet (). stream () .collect (Collectors.toMap (e -> e.getKey (), e -> e.getValue (). שווה (שנייה. קבל (e.getKey ())))); }
כעת אנו יכולים להשתמש areEqualKeyValues () להשוות בין שני שונים HashMaps כדי לראות בפירוט אילו מקשים הם בעלי אותו ערך ואילו ערכים שונים:
@ מבחן ציבורי בטל כאשרCompareTwoHashMapKeyValuesUsingStreamAPI_thenSuccess () {Map asiaCapital3 = HashMap חדש (); asiaCapital3.put ("יפן", "טוקיו"); asiaCapital3.put ("דרום קוריאה", "סיאול"); asiaCapital3.put ("סין", "בייג'ינג"); מפה asiaCapital4 = HashMap חדש (); asiaCapital4.put ("דרום קוריאה", "סיאול"); asiaCapital4.put ("יפן", "אוסקה"); asiaCapital4.put ("סין", "בייג'ינג"); תוצאת מפה = areEqualKeyValues (asiaCapital3, asiaCapital4); assertEquals (3, result.size ()); assertThat (תוצאה, hasEntry ("יפן", שקר)); assertThat (תוצאה, hasEntry ("דרום קוריאה", נכון)); assertThat (תוצאה, hasEntry ("סין", נכון)); }
5. הבדל מפה באמצעות גויאבה
לבסוף נראה כיצד להשיג הבדל מפורט בין שניים HashMaps באמצעות גויאבה מפות. הבדל ().
שיטה זו מחזירה א MapDifference אובייקט שיש לו מספר שיטות שימושיות לניתוח ההבדל בין מפות. בואו נסתכל על כמה מאלה.
5.1. MapDifference.entriesDiffering ()
ראשית, נשיג מקשים נפוצים הכוללים ערכים שונים בכל אחד מהם מפת גיבוב באמצעות MapDifference.entriesDiffering ():
@Test public void givenDifferentMaps_whenGetDiffUsingGuava_thenSuccess () {Map asia1 = HashMap new (); asia1.put ("יפן", "טוקיו"); asia1.put ("דרום קוריאה", "סיאול"); asia1.put ("הודו", "ניו דלהי"); מפה asia2 = HashMap חדש (); asia2.put ("יפן", "טוקיו"); asia2.put ("סין", "בייג'ינג"); asia2.put ("הודו", "דלהי"); MapDifference diff = Maps.difference (asia1, asia2); מַפָּה entriesDiffering = diff.entriesDiffering (); assertFalse (diff.areEqual ()); assertEquals (1, entriesDiffering.size ()); assertThat (entriesDiffering, hasKey ("הודו")); assertEquals ("ניו דלהי", entriesDiffering.get ("הודו"). leftValue ()); assertEquals ("דלהי", entriesDiffering.get ("הודו"). rightValue ()); }
ה ערכים הבדל () שיטה מחזירה חדשה מַפָּה המכיל את קבוצת המפתחות הנפוצים ו- ValueDifference אובייקטים כקבוצת הערכים.
כל אחד ValueDifference לאובייקט יש leftValue () ו rightValue () שיטות שמחזירות את הערכים בשניים מפותבהתאמה.
5.2. MapDifference.entriesOnlyOnRight () ו MapDifference.entriesOnlyOnLeft ()
לאחר מכן, אנו יכולים לקבל רשומות שקיימות רק באחד מפת גיבוב באמצעות MapDifference.entriesOnlyOnRight () ו MapDifference.entriesOnlyOnLeft ():
@Test public void givenDifferentMaps_whenGetEntriesOnOneSideUsingGuava_thenSuccess () {MapDifference diff = Maps.difference (asia1, asia2); ערכי מפהOnlyOnRight = diff.entriesOnlyOnRight (); ערכי מפהOnlyOnLeft = diff.entriesOnlyOnLeft (); assertEquals (1, entriesOnlyOnRight.size ()); assertEquals (1, entriesOnlyOnLeft.size ()); assertThat (entriesOnlyOnRight, hasEntry ("סין", "בייג'ינג")); assertThat (entriesOnlyOnLeft, hasEntry ("דרום קוריאה", "סיאול")); }
5.3. MapDifference.entriesInCommon ()
הַבָּא, נקבל ערכים נפוצים באמצעות MapDifference.entriesInCommon ():
@ מבט ציבורי בטל givenDifferentMaps_whenGetCommonEntriesUsingGuava_thenSuccess () {MapDifference diff = Maps.difference (asia1, asia2); ערכי מפהInCommon = diff.entriesInCommon (); assertEquals (1, entriesInCommon.size ()); assertThat (entriesInCommon, hasEntry ("יפן", "טוקיו")); }
5.4. התאמה אישית מפות. הבדל () התנהגות
מאז מפות. הבדל () להשתמש שווים() ו hashCode () כברירת מחדל להשוואת ערכים, זה לא יעבוד עבור אובייקטים שלא מיישמים אותם כראוי:
@Test public void givenSimilarMapsWithArrayValue_whenCompareUsingGuava_thenFail () {MapDifference diff = Maps.difference (asiaCity1, asiaCity2); assertFalse (diff.areEqual ()); }
אבל, אנו יכולים להתאים אישית את השיטה בה משתמשים בהשוואה שְׁקִילוּת.
לדוגמא, נגדיר שְׁקִילוּת לסוג חוּט[] להשוות חוּט[] ערכים שלנו HashMaps כמו שאנחנו אוהבים:
@Test public void givenSimilarMapsWithArrayValue_whenCompareUsingGuavaEquivalence_thenSuccess () {Equivalence eq = new Equivalence () {@Override מוגן בוליאני doEquivalent (מחרוזת [] a, מחרוזת [] b) {החזר מערכים. שוויון (a, b); } @Override מוגן int doHash (ערך מחרוזת []) {return value.hashCode (); }}; MapDifference diff = Maps.difference (asiaCity1, asiaCity2, eq); assertTrue (diff.areEqual ()); diff = Maps.difference (asiaCity1, asiaCity3, eq); assertFalse (diff.areEqual ()); }
6. מסקנה
במאמר זה דנו בדרכים שונות להשוואה HashMaps בג'אווה. למדנו דרכים מרובות לבדוק אם שתיים HashMaps שווים וכיצד להשיג גם את ההבדל המפורט.
קוד המקור המלא זמין ב- GitHub.