Sammenligning af to HashMaps i Java

1. Oversigt

I denne vejledning vi skal undersøge forskellige måder at sammenligne to på HashMaps i Java.

Vi diskuterer flere måder at kontrollere, om to HashMaps er ens. Vi bruger også Java 8 Stream API og Guava til at få de detaljerede forskelle mellem forskellige HashMaps.

2. Brug Map.equals ()

Først bruger vi Map.equals () for at kontrollere, om to HashMaps har de samme poster:

@Test offentlig ugyldig nårCompareTwoHashMapsUsingEquals_thenSuccess () {Map asiaCapital1 = ny HashMap (); asiaCapital1.put ("Japan", "Tokyo"); asiaCapital1.put ("Sydkorea", "Seoul"); Kort asiaCapital2 = nyt HashMap (); asiaCapital2.put ("Sydkorea", "Seoul"); asiaCapital2.put ("Japan", "Tokyo"); Kort asiaCapital3 = nyt HashMap (); asiaCapital3.put ("Japan", "Tokyo"); asiaCapital3.put ("Kina", "Beijing"); hævder sandt (asiaCapital1.equals (asiaCapital2)); hævder Falsk (asiaCapital1.equals (asiaCapital3)); }

Her opretter vi tre HashMap objekter og tilføjelse af poster. Så bruger vi Map.equals () for at kontrollere, om to HashMaps har de samme poster.

Sådan Map.equals () fungerer ved at sammenligne nøgler og værdier ved hjælp af Objekt. Ligestilling () metode. Dette betyder, at det kun fungerer, når både nøgle- og værdiobjekter implementeres lige med() korrekt.

For eksempel, Map.equals () fungerer ikke, når værditypen er matrix, som en matrix lige med() metode sammenligner identitet og ikke indholdet af arrayet:

@Test offentlig ugyldig nårCompareTwoHashMapsWithArrayValuesUsingEquals_thenFail () {Map asiaCity1 = ny HashMap (); asiaCity1.put ("Japan", ny streng [] {"Tokyo", "Osaka"}); asiaCity1.put ("Sydkorea", ny streng [] {"Seoul", "Busan"}); Kort asiaCity2 = nyt HashMap (); asiaCity2.put ("Sydkorea", ny streng [] {"Seoul", "Busan"}); asiaCity2.put ("Japan", ny streng [] {"Tokyo", "Osaka"}); assertFalse (asiaCity1.equals (asiaCity2)); }

3. Brug af Java Strøm API

Vi kan også implementere vores egen metode til sammenligning HashMaps ved hjælp af Java 8 Strøm API:

private boolske areEqual (kort først, kort andet) {if (first.size ()! = second.size ()) {return false; } returner first.entrySet (). stream () .allMatch (e -> e.getValue (). er lig med (second.get (e.getKey ()))); }

For enkelheds skyld implementerede vi areEqual () metode, som vi nu kan bruge til at sammenligne HashMap genstande:

@Test offentligt ugyldigt nårCompareTwoHashMapsUsingStreamAPI_thenSuccess () {assertTrue (areEqual (asiaCapital1, asiaCapital2)); hævder Falsk (areEqual (asiaCapital1, asiaCapital3)); }

Men vi kan også tilpasse vores egen metode areEqualWithArrayValue () til at håndtere matrixværdier ved hjælp af Arrays.equals () at sammenligne to arrays:

private boolske areEqualWithArrayValue (kort først, kort andet) {if (first.size ()! = second.size ()) {return false; } returner first.entrySet (). stream () .allMatch (e -> Arrays.equals (e.getValue (), second.get (e.getKey ()))); }

I modsætning til Map.equals (), vil vores egen metode med succes sammenligne HashMaps med matrixværdier:

@Test offentligt ugyldigt nårCompareTwoHashMapsWithArrayValuesUsingStreamAPI_thenSuccess () {assertTrue (areEqualWithArrayValue (asiaCity1, asiaCity2)); assertFalse (areEqualWithArrayValue (asiaCity1, asiaCity3)); }

4. Sammenligning HashMap Nøgler og værdier

Lad os derefter se, hvordan man sammenligner to HashMap taster og deres tilsvarende værdier.

4.1. Sammenligning HashMap Nøgler

Først kan vi kontrollere, om to HashMaps har de samme nøgler ved bare at sammenligne deres Nøglesæt ():

@Test offentlig ugyldig nårCompareTwoHashMapKeys_thenSuccess () {assertTrue (asiaCapital1.keySet (). Er lig med (asiaCapital2.keySet ())); assertFalse (asiaCapital1.keySet (). er lig med (asiaCapital3.keySet ())); }

4.2. Sammenligning HashMap Værdier

Derefter ser vi, hvordan man sammenligner HashMap værdier en efter en.

Vi implementerer en enkel metode til at kontrollere, hvilke nøgler der har samme værdi i begge HashMaps ved brug af Strøm API:

private Map areEqualKeyValues ​​(Map first, Map second) {return first.entrySet (). stream () .collect (Collectors.toMap (e -> e.getKey (), e -> e.getValue (). lig med (second. få (e.getKey ())))); }

Vi kan nu bruge areEqualKeyValues ​​() at sammenligne to forskellige HashMaps for at se detaljeret, hvilke taster der har den samme værdi, og hvilke der har forskellige værdier:

@Test offentlig ugyldig nårCompareTwoHashMapKeyValuesUsingStreamAPI_thenSuccess () {Map asiaCapital3 = ny HashMap (); asiaCapital3.put ("Japan", "Tokyo"); asiaCapital3.put ("Sydkorea", "Seoul"); asiaCapital3.put ("Kina", "Beijing"); Kort asiaCapital4 = nyt HashMap (); asiaCapital4.put ("Sydkorea", "Seoul"); asiaCapital4.put ("Japan", "Osaka"); asiaCapital4.put ("Kina", "Beijing"); Kortresultat = areEqualKeyValues ​​(asiaCapital3, asiaCapital4); assertEquals (3, result.size ()); assertThat (resultat, hasEntry ("Japan", falsk)); assertThat (resultat, hasEntry ("Sydkorea", sandt)); assertThat (resultat, hasEntry ("Kina", sandt)); }

5. Kortforskel ved hjælp af Guava

Endelig får vi se hvordan man får en detaljeret forskel mellem to HashMaps ved hjælp af Guava Kort. Forskel ().

Denne metode returnerer a Kortforskel objekt, der har en række nyttige metoder til at analysere forskellen mellem Kort. Lad os se på nogle af disse.

5.1. MapDifference.entriesDiffering ()

Først får vi det fælles nøgler, der har forskellige værdier i hver HashMap ved brug af MapDifference.entriesDiffering ():

@Test offentlig ugyldighed givenDifferentMaps_whenGetDiffUsingGuava_thenSuccess () {Map asia1 = new HashMap (); asia1.put ("Japan", "Tokyo"); asia1.put ("Sydkorea", "Seoul"); asia1.put ("Indien", "New Delhi"); Kort asia2 = nyt HashMap (); asia2.put ("Japan", "Tokyo"); asia2.put ("Kina", "Beijing"); asia2.put ("Indien", "Delhi"); MapDifference diff = Maps.difference (asia1, asia2); Kort entriesDiffering = diff.entriesDiffering (); assertFalse (diff.areEqual ()); assertEquals (1, entriesDiffering.size ()); assertThat (entriesDiffering, hasKey ("Indien")); assertEquals ("New Delhi", entriesDiffering.get ("Indien"). leftValue ()); assertEquals ("Delhi", entriesDiffering.get ("Indien"). rightValue ()); }

Det posterDiffering () metode returnerer en ny Kort der indeholder sættet med fælles nøgler og Værdiforskel objekter som sæt af værdier.

Hver Værdiforskel objekt har en leftValue () og rightValue () metoder, der returnerer værdierne i de to Korthenholdsvis.

5.2. MapDifference.entriesOnlyOnRight () og MapDifference.entriesOnlyOnLeft ()

Derefter kan vi få poster, der kun findes i en HashMap ved brug af MapDifference.entriesOnlyOnRight () og MapDifference.entriesOnlyOnLeft ():

@ Test offentlig ugyldighed givenDifferentMaps_whenGetEntriesOnOneSideUsingGuava_thenSuccess () {MapDifference diff = Maps.difference (asia1, asia2); KortindgangeOnlyOnRight = diff.entriesOnlyOnRight (); KortindgangeOnlyOnLeft = diff.entriesOnlyOnLeft (); assertEquals (1, entriesOnlyOnRight.size ()); assertEquals (1, entriesOnlyOnLeft.size ()); assertThat (entriesOnlyOnRight, hasEntry ("Kina", "Beijing")); assertThat (entriesOnlyOnLeft, hasEntry ("Sydkorea", "Seoul")); }

5.3. MapDifference.entriesInCommon ()

Næste, vi får almindelige poster ved hjælp af MapDifference.entriesInCommon ():

@ Test offentlig ugyldighed givenDifferentMaps_whenGetCommonEntriesUsingGuava_thenSuccess () {MapDifference diff = Maps.difference (asia1, asia2); Map entriesInCommon = diff.entriesInCommon (); assertEquals (1, entriesInCommon.size ()); assertThat (entriesInCommon, hasEntry ("Japan", "Tokyo")); }

5.4. Tilpasning Maps.difference () Opførsel

Siden Maps.difference () brug lige med() og hashCode () som standard for at sammenligne poster fungerer det ikke for objekter, der ikke implementerer dem ordentligt:

@Test offentlig ugyldighed givenSimilarMapsWithArrayValue_whenCompareUsingGuava_thenFail () {MapDifference diff = Maps.difference (asiaCity1, asiaCity2); assertFalse (diff.areEqual ()); }

Men, vi kan tilpasse metoden, der bruges i sammenligning ved hjælp af Ækvivalens.

For eksempel definerer vi Ækvivalens for type Snor[] at sammenligne Snor[] værdier i vores HashMaps som vi kan lide:

@Test offentlig ugyldighed givenSimilarMapsWithArrayValue_whenCompareUsingGuavaEquivalence_thenSuccess () {Equivalence eq = new Equivalence () {@ Override protected boolean doEquivalent (String [] a, String [] b) {return Arrays.equals (a, b); } @ Override beskyttet int doHash (streng [] værdi) {return value.hashCode (); }}; MapDifference diff = Maps.difference (asiaCity1, asiaCity2, eq); assertTrue (diff.areEqual ()); diff = Maps.difference (asiaCity1, asiaCity3, eq); assertFalse (diff.areEqual ()); }

6. Konklusion

I denne artikel diskuterede vi forskellige måder at sammenligne på HashMaps i Java. Vi lærte flere måder at kontrollere, om to HashMaps er lige, og hvordan man også får den detaljerede forskel.

Den fulde kildekode er tilgængelig på GitHub.