1. Übersicht
In diesem Tutorial werden wir verschiedene Möglichkeiten untersuchen, um zwei HashMaps in Java zu vergleichen .
Wir werden verschiedene Möglichkeiten diskutieren, um zu überprüfen, ob zwei HashMaps ähnlich sind. Wir werden auch Java 8 Stream API und Guava verwenden, um die detaillierten Unterschiede zwischen verschiedenen HashMaps zu ermitteln .
2. Verwenden von Map.equals ()
Zuerst verwenden wir Map.equals () , um zu überprüfen, ob zwei HashMaps dieselben Einträge haben:
@Test public void whenCompareTwoHashMapsUsingEquals_thenSuccess() { Map asiaCapital1 = new HashMap(); asiaCapital1.put("Japan", "Tokyo"); asiaCapital1.put("South Korea", "Seoul"); Map asiaCapital2 = new HashMap(); asiaCapital2.put("South Korea", "Seoul"); asiaCapital2.put("Japan", "Tokyo"); Map asiaCapital3 = new HashMap(); asiaCapital3.put("Japan", "Tokyo"); asiaCapital3.put("China", "Beijing"); assertTrue(asiaCapital1.equals(asiaCapital2)); assertFalse(asiaCapital1.equals(asiaCapital3)); }
Hier erstellen wir drei HashMap- Objekte und fügen Einträge hinzu. Dann verwenden wir Map.equals () , um zu überprüfen, ob zwei HashMaps dieselben Einträge haben.
Die Art und Weise , dass Map.equals () funktioniert , ist durch Verwendung von Schlüsseln und Werten des Vergleich Object.equals () Methode . Dies bedeutet, dass es nur funktioniert, wenn sowohl Schlüssel- als auch Wertobjekte equals () ordnungsgemäß implementieren .
Zum Beispiel funktioniert Map.equals () nicht, wenn der Werttyp Array ist, da die equals () -Methode eines Arrays die Identität und nicht den Inhalt des Arrays vergleicht:
@Test public void whenCompareTwoHashMapsWithArrayValuesUsingEquals_thenFail() { Map asiaCity1 = new HashMap(); asiaCity1.put("Japan", new String[] { "Tokyo", "Osaka" }); asiaCity1.put("South Korea", new String[] { "Seoul", "Busan" }); Map asiaCity2 = new HashMap(); asiaCity2.put("South Korea", new String[] { "Seoul", "Busan" }); asiaCity2.put("Japan", new String[] { "Tokyo", "Osaka" }); assertFalse(asiaCity1.equals(asiaCity2)); }
3. Verwenden der Java Stream- API
Wir können auch unsere eigene Methode implementieren, um HashMaps mithilfe der Java 8 Stream- API zu vergleichen :
private boolean areEqual(Map first, Map second) { if (first.size() != second.size()) { return false; } return first.entrySet().stream() .allMatch(e -> e.getValue().equals(second.get(e.getKey()))); }
Der Einfachheit halber haben wir die areEqual () -Methode implementiert, mit der wir jetzt HashMap- Objekte vergleichen können:
@Test public void whenCompareTwoHashMapsUsingStreamAPI_thenSuccess() { assertTrue(areEqual(asiaCapital1, asiaCapital2)); assertFalse(areEqual(asiaCapital1, asiaCapital3)); }
Wir können aber auch unsere eigene Methode areEqualWithArrayValue () anpassen , um Array-Werte zu verarbeiten, indem wir Arrays.equals () verwenden , um zwei Arrays zu vergleichen:
private boolean areEqualWithArrayValue(Map first, Map second) { if (first.size() != second.size()) { return false; } return first.entrySet().stream() .allMatch(e -> Arrays.equals(e.getValue(), second.get(e.getKey()))); }
Im Gegensatz zu Map.equals () vergleicht unsere eigene Methode HashMaps erfolgreich mit Array-Werten:
@Test public void whenCompareTwoHashMapsWithArrayValuesUsingStreamAPI_thenSuccess() { assertTrue(areEqualWithArrayValue(asiaCity1, asiaCity2)); assertFalse(areEqualWithArrayValue(asiaCity1, asiaCity3)); }
4. Vergleichen von HashMap- Schlüsseln und -Werten
Als nächstes wollen wir sehen, wie zwei HashMap- Schlüssel und ihre entsprechenden Werte verglichen werden.
4.1. Im Vergleich HashMap Keys
Zunächst können wir überprüfen, ob zwei HashMaps dieselben Schlüssel haben, indem wir nur ihr KeySet () vergleichen :
@Test public void whenCompareTwoHashMapKeys_thenSuccess() { assertTrue(asiaCapital1.keySet().equals(asiaCapital2.keySet())); assertFalse(asiaCapital1.keySet().equals(asiaCapital3.keySet())); }
4.2. Vergleicht man HashMap Werte
Als nächstes sehen wir, wie HashMap- Werte einzeln verglichen werden.
Wir implementieren eine einfache Methode, um mithilfe der Stream- API zu überprüfen, welche Schlüssel in beiden HashMaps denselben Wert haben :
private Map areEqualKeyValues(Map first, Map second) { return first.entrySet().stream() .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue().equals(second.get(e.getKey())))); }
Wir können jetzt areEqualKeyValues () verwenden , um zwei verschiedene HashMaps zu vergleichen und im Detail zu sehen, welche Schlüssel denselben Wert und welche unterschiedliche Werte haben:
@Test public void whenCompareTwoHashMapKeyValuesUsingStreamAPI_thenSuccess() { Map asiaCapital3 = new HashMap(); asiaCapital3.put("Japan", "Tokyo"); asiaCapital3.put("South Korea", "Seoul"); asiaCapital3.put("China", "Beijing"); Map asiaCapital4 = new HashMap(); asiaCapital4.put("South Korea", "Seoul"); asiaCapital4.put("Japan", "Osaka"); asiaCapital4.put("China", "Beijing"); Map result = areEqualKeyValues(asiaCapital3, asiaCapital4); assertEquals(3, result.size()); assertThat(result, hasEntry("Japan", false)); assertThat(result, hasEntry("South Korea", true)); assertThat(result, hasEntry("China", true)); }
5. Kartenunterschied mit Guave
Schließlich werden wir sehen, wie Sie mit Guava Maps.difference () einen detaillierten Unterschied zwischen zwei HashMaps ermitteln.
Diese Methode gibt ein MapDifference- Objekt zurück, das über eine Reihe nützlicher Methoden verfügt, um den Unterschied zwischen den Maps zu analysieren . Schauen wir uns einige davon an.
5.1. MapDifference.entriesDiffering ()
Zuerst erhalten wir mit MapDifference.entriesDiffering () gemeinsame Schlüssel, die in jeder HashMap unterschiedliche Werte haben :
@Test public void givenDifferentMaps_whenGetDiffUsingGuava_thenSuccess() { Map asia1 = new HashMap(); asia1.put("Japan", "Tokyo"); asia1.put("South Korea", "Seoul"); asia1.put("India", "New Delhi"); Map asia2 = new HashMap(); asia2.put("Japan", "Tokyo"); asia2.put("China", "Beijing"); asia2.put("India", "Delhi"); MapDifference diff = Maps.difference(asia1, asia2); Map
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()); }
Die Methode entryDiffering () gibt eine neue Map zurück , die den Satz allgemeiner Schlüssel und ValueDifference- Objekte als Satz von Werten enthält.
Jedes ValueDifference- Objekt verfügt über die Methoden leftValue () und rightValue () , die die Werte in den beiden Maps zurückgeben .
5.2. MapDifference.entriesOnlyOnRight () und MapDifference.entriesOnlyOnLeft ()
Dann können wir mit MapDifference.entriesOnlyOnRight () und MapDifference.entriesOnlyOnLeft () Einträge abrufen , die nur in einer HashMap vorhanden sind :
@Test public void givenDifferentMaps_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("South Korea", "Seoul")); }
5.3. MapDifference.entriesInCommon ()
Als Nächstes erhalten wir allgemeine Einträge mit MapDifference.entriesInCommon ():
@Test public void givenDifferentMaps_whenGetCommonEntriesUsingGuava_thenSuccess() { MapDifference diff = Maps.difference(asia1, asia2); Map entriesInCommon = diff.entriesInCommon(); assertEquals(1, entriesInCommon.size()); assertThat(entriesInCommon, hasEntry("Japan", "Tokyo")); }
5.4. Anpassen des Verhaltens von Maps.difference ()
Da Maps.difference () Verwendung equals () und hashCode () durch Standardeinträge vergleichen zu können , wird es nicht funktioniert für Objekte , die sie nicht richtig implementieren:
@Test public void givenSimilarMapsWithArrayValue_whenCompareUsingGuava_thenFail() { MapDifference diff = Maps.difference(asiaCity1, asiaCity2); assertFalse(diff.areEqual()); }
Aber können wir das Verfahren im Vergleich verwendet , um anpassen Equivalence .
Zum Beispiel definieren wir die Äquivalenz für den Typ String [] , um die Werte von String [] in unseren HashMaps nach Belieben zu vergleichen :
@Test public void givenSimilarMapsWithArrayValue_whenCompareUsingGuavaEquivalence_thenSuccess() { Equivalence eq = new Equivalence() { @Override protected boolean doEquivalent(String[] a, String[] b) { return Arrays.equals(a, b); } @Override protected int doHash(String[] value) { return value.hashCode(); } }; MapDifference diff = Maps.difference(asiaCity1, asiaCity2, eq); assertTrue(diff.areEqual()); diff = Maps.difference(asiaCity1, asiaCity3, eq); assertFalse(diff.areEqual()); }
6. Fazit
In diesem Artikel haben wir verschiedene Möglichkeiten zum Vergleichen von HashMaps in Java erläutert . Wir haben mehrere Möglichkeiten kennengelernt , um zu überprüfen, ob zwei HashMaps gleich sind und wie der detaillierte Unterschied ermittelt werden kann.
Der vollständige Quellcode ist auf GitHub verfügbar.