Twee HashMaps in Java vergelijken

1. Overzicht

In deze tutorial we gaan verschillende manieren onderzoeken om twee te vergelijken HashMaps in Java.

We bespreken meerdere manieren om te controleren of er twee zijn HashMaps Zijn hetzelfde. We zullen ook Java 8 Stream API en Guava gebruiken om de gedetailleerde verschillen tussen verschillende HashMaps.

2. Met behulp van Map.equals ()

Eerst gebruiken we Map.equals () om te controleren of twee HashMaps hebben dezelfde vermeldingen:

@Test openbare leegte whenCompareTwoHashMapsUsingEquals_thenSuccess () {Map asiaCapital1 = nieuwe HashMap (); asiaCapital1.put ("Japan", "Tokio"); asiaCapital1.put ("Zuid-Korea", "Seoul"); Kaart asiaCapital2 = nieuwe HashMap (); asiaCapital2.put ("Zuid-Korea", "Seoul"); asiaCapital2.put ("Japan", "Tokio"); Kaart asiaCapital3 = nieuwe HashMap (); asiaCapital3.put ("Japan", "Tokio"); asiaCapital3.put ("China", "Peking"); assertTrue (asiaCapital1.equals (asiaCapital2)); assertFalse (asiaCapital1.equals (asiaCapital3)); }

Hier maken we er drie Hash kaart objecten en invoeren. Dan gebruiken we Map.equals () om te controleren of twee HashMaps dezelfde vermeldingen hebben.

De manier waarop Map.equals () works is door sleutels en waarden te vergelijken met behulp van de Object.equals () methode. Dit betekent dat het alleen werkt als zowel sleutel- als waardeobjecten worden geïmplementeerd is gelijk aan () naar behoren.

Bijvoorbeeld, Map.equals () werkt niet als het waardetype array is, zoals dat van een array is gelijk aan () methode vergelijkt identiteit en niet de inhoud van de array:

@Test openbare leegte whenCompareTwoHashMapsWithArrayValuesUsingEquals_thenFail () {Map asiaCity1 = nieuwe HashMap (); asiaCity1.put ("Japan", nieuwe String [] {"Tokyo", "Osaka"}); asiaCity1.put ("Zuid-Korea", nieuwe String [] {"Seoul", "Busan"}); Map asiaCity2 = nieuwe HashMap (); asiaCity2.put ("Zuid-Korea", nieuwe String [] {"Seoul", "Busan"}); asiaCity2.put ("Japan", nieuwe String [] {"Tokyo", "Osaka"}); assertFalse (asiaCity1.equals (asiaCity2)); }

3. Met behulp van de Java Stroom API

We kunnen ook onze eigen methode implementeren om te vergelijken HashMaps met behulp van de Java 8 Stroom API:

private boolean areEqual (Map eerst, Map tweede) {if (first.size ()! = second.size ()) {return false; } return first.entrySet (). stream () .allMatch (e -> e.getValue (). equals (second.get (e.getKey ()))); }

Voor de eenvoud hebben we het zijn gelijk() methode die we nu kunnen gebruiken om te vergelijken Hash kaart voorwerpen:

@Test openbare leegte whenCompareTwoHashMapsUsingStreamAPI_thenSuccess () {assertTrue (areEqual (asiaCapital1, asiaCapital2)); assertFalse (areEqual (asiaCapital1, asiaCapital3)); }

Maar we kunnen ook onze eigen methode aanpassen areEqualWithArrayValue () om matrixwaarden af ​​te handelen met Arrays.equals () om twee arrays te vergelijken:

private boolean areEqualWithArrayValue (Map eerst, Map tweede) {if (first.size ()! = second.size ()) {return false; } return first.entrySet (). stream () .allMatch (e -> Arrays.equals (e.getValue (), second.get (e.getKey ()))); }

in tegenstelling tot Map.equals (), zal onze eigen methode met succes vergelijken HashMaps met matrixwaarden:

@Test openbare leegte whenCompareTwoHashMapsWithArrayValuesUsingStreamAPI_thenSuccess () {assertTrue (areEqualWithArrayValue (asiaCity1, asiaCity2)); assertFalse (areEqualWithArrayValue (asiaCity1, asiaCity3)); }

4. Vergelijken Hash kaart Sleutels en waarden

Laten we vervolgens kijken hoe we twee kunnen vergelijken Hash kaart sleutels en hun bijbehorende waarden.

4.1. Vergelijken Hash kaart Sleutels

Ten eerste kunnen we controleren of er twee zijn HashMaps dezelfde sleutels hebben door hun Sleutelbos():

@Test openbare leegte whenCompareTwoHashMapKeys_thenSuccess () {assertTrue (asiaCapital1.keySet (). Equals (asiaCapital2.keySet ())); assertFalse (asiaCapital1.keySet (). is gelijk aan (asiaCapital3.keySet ())); }

4.2. Vergelijken Hash kaart Waarden

Vervolgens zullen we zien hoe we kunnen vergelijken Hash kaart waarden een voor een.

We zullen een eenvoudige methode implementeren om te controleren welke sleutels in beide dezelfde waarde hebben HashMaps gebruik makend van Stroom API:

private Map areEqualKeyValues ​​(Map eerst, Map tweede) {return first.entrySet (). stream () .collect (Collectors.toMap (e -> e.getKey (), e -> e.getValue (). equals (second. get (e.getKey ())))); }

We kunnen nu gebruiken areEqualKeyValues ​​() om twee verschillende te vergelijken HashMaps om in detail te zien welke sleutels dezelfde waarde hebben en welke verschillende waarden hebben:

@Test openbare leegte whenCompareTwoHashMapKeyValuesUsingStreamAPI_thenSuccess () {Map asiaCapital3 = nieuwe HashMap (); asiaCapital3.put ("Japan", "Tokio"); asiaCapital3.put ("Zuid-Korea", "Seoul"); asiaCapital3.put ("China", "Peking"); Kaart asiaCapital4 = nieuwe HashMap (); asiaCapital4.put ("Zuid-Korea", "Seoul"); asiaCapital4.put ("Japan", "Osaka"); asiaCapital4.put ("China", "Peking"); Kaartresultaat = areEqualKeyValues ​​(asiaCapital3, asiaCapital4); assertEquals (3, result.size ()); assertThat (result, hasEntry ("Japan", false)); assertThat (result, hasEntry ("Zuid-Korea", true)); assertThat (result, hasEntry ("China", true)); }

5. Breng het verschil in kaart met behulp van Guava

Eindelijk zullen we zien hoe u een gedetailleerd verschil tussen twee kunt krijgen HashMaps met behulp van Guava Maps.difference ().

Deze methode retourneert een MapDifference object dat een aantal handige methoden heeft om het verschil tussen de Kaarten. Laten we een paar van deze bekijken.

5.1. MapDifference.entriesDiffering ()

Ten eerste zullen we verkrijgen gemeenschappelijke sleutels die in elk verschillende waarden hebben Hash kaart gebruik makend van MapDifference.entriesDiffering ():

@Test openbare leegte gegevenDifferentMaps_whenGetDiffUsingGuava_thenSuccess () {Map asia1 = nieuwe HashMap (); asia1.put ("Japan", "Tokio"); asia1.put ("Zuid-Korea", "Seoul"); asia1.put ("India", "New Delhi"); Map asia2 = nieuwe HashMap (); asia2.put ("Japan", "Tokio"); asia2.put ("China", "Peking"); asia2.put ("India", "Delhi"); MapDifference diff = Maps.difference (asia1, asia2); Kaart entriesDiffering = diff.entriesDiffering (); assertFalse (diff.areEqual ()); assertEquals (1, entriesDiffering.size ()); assertThat (entriesDiffering, hasKey ("India")); assertEquals ("New Delhi", entriesDiffering.get ("India"). leftValue ()); assertEquals ("Delhi", entriesDiffering.get ("India"). rightValue ()); }

De inzendingenDiffering () methode retourneert een nieuw Kaart die de set gemeenschappelijke sleutels bevat en ValueVerschil objecten als de set waarden.

Elk ValueVerschil object heeft een leftValue () en rightValue () methoden die de waarden in de twee retourneren Kaartenrespectievelijk.

5.2. MapDifference.entriesOnlyOnRight () en MapDifference.entriesOnlyOnLeft ()

Vervolgens kunnen we vermeldingen krijgen die in slechts één bestaan Hash kaart gebruik makend van MapDifference.entriesOnlyOnRight () en MapDifference.entriesOnlyOnLeft ():

@Test openbare leegte gegevenDifferentMaps_whenGetEntriesOnOneSideUsingGuava_thenSuccess () {MapDifference diff = Maps.difference (asia1, asia2); Map entriesOnlyOnRight = diff.entriesOnlyOnRight (); Map entriesOnlyOnLeft = diff.entriesOnlyOnLeft (); assertEquals (1, entriesOnlyOnRight.size ()); assertEquals (1, entriesOnlyOnLeft.size ()); assertThat (entriesOnlyOnRight, hasEntry ("China", "Beijing")); assertThat (entriesOnlyOnLeft, hasEntry ("Zuid-Korea", "Seoul")); }

5.3. MapDifference.entriesInCommon ()

De volgende, we krijgen veelvoorkomende vermeldingen met MapDifference.entriesInCommon ():

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

5.4. Aanpassen Maps.difference () Gedrag

Sinds Maps.difference () gebruik is gelijk aan () en hashCode () standaard om items te vergelijken, werkt het niet voor objecten die ze niet correct implementeren:

@Test openbare ongeldige gegevenSimilarMapsWithArrayValue_whenCompareUsingGuava_thenFail () {MapDifference diff = Maps.difference (asiaCity1, asiaCity2); assertFalse (diff.areEqual ()); }

Maar, we kunnen de gebruikte methode in vergelijking aanpassen met Gelijkwaardigheid.

We zullen bijvoorbeeld definiëren Gelijkwaardigheid voor type Draad[] om te vergelijken Draad[] waarden in onze HashMaps zoals we willen:

@Test openbare ongeldige gegevenSimilarMapsWithArrayValue_whenCompareUsingGuavaEquivalence_thenSuccess () {Equivalence eq = new Equivalence () {@Override beschermd boolean doEquivalent (String [] a, String [] b) {return Arrays.equals (a, b) {return Arrays.equals (a, b); } @Override protected int doHash (String [] waarde) {return value.hashCode (); }}; MapDifference diff = Maps.difference (asiaCity1, asiaCity2, eq); assertTrue (diff.areEqual ()); diff = Maps.difference (asiaCity1, asiaCity3, eq); assertFalse (diff.areEqual ()); }

6. Conclusie

In dit artikel hebben we verschillende manieren besproken om te vergelijken HashMaps in Java. We hebben meerdere manieren geleerd om te controleren of er twee zijn HashMaps zijn gelijk en hoe u ook het gedetailleerde verschil kunt krijgen.

De volledige broncode is beschikbaar op GitHub.