Сравнение двух хэш-карт на Java
1. Обзор
В этом учебнике мы собираемся изучить различные способы сравнения двух HashMaps в Java .
Мы обсудим несколько способов проверить, если два HashMaps похожи. Мы также будем использовать Java 8 Stream API и Guava, чтобы получить подробные различия между различными HashMaps .
2. Использование Map.equals ()
Во-первых, мы будем использовать Map.equals () чтобы проверить, если два HashMaps имеют те же записи:
@Test public void whenCompareTwoHashMapsUsingEquals_thenSuccess() { MapasiaCapital1 = 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)); }
Здесь мы создаем три HashMap объектов и добавление записей. Тогда мы используем Map.equals () чтобы проверить, если два HashMaps имеют те же записи.
Так, как Map.equals () работы путем сравнения ключей и значений с помощью Object.equals () метод . Это означает, что он работает только тогда, когда как ключевые, так и ценностные объекты равны () правильно.
Например, Map.equals () не работает, когда тип значения массив, как равны () метод сравнивает идентичность, а не содержимое массива:
@Test public void whenCompareTwoHashMapsWithArrayValuesUsingEquals_thenFail() { MapasiaCity1 = 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. Использование API Java Stream
Мы также можем внедрить наш собственный метод для сравнения ХэшМэпс с помощью Java 8 поток API:
private boolean areEqual(Mapfirst, Map second) { if (first.size() != second.size()) { return false; } return first.entrySet().stream() .allMatch(e -> e.getValue().equals(second.get(e.getKey()))); }
Для простоты мы внедрили areEqual () метод, который мы теперь можем использовать для сравнения Объекты HashMap
@Test public void whenCompareTwoHashMapsUsingStreamAPI_thenSuccess() { assertTrue(areEqual(asiaCapital1, asiaCapital2)); assertFalse(areEqual(asiaCapital1, asiaCapital3)); }
Но мы также можем настроить наш собственный метод areEqualWithArrayValue () для обработки значений массива с помощью Arrays.equals () для сравнения двух массивов:
private boolean areEqualWithArrayValue(Mapfirst, Map second) { if (first.size() != second.size()) { return false; } return first.entrySet().stream() .allMatch(e -> Arrays.equals(e.getValue(), second.get(e.getKey()))); }
В отличие от Map.equals () , наш собственный метод будет успешно сравнивать HashMaps с значениями массива:
@Test public void whenCompareTwoHashMapsWithArrayValuesUsingStreamAPI_thenSuccess() { assertTrue(areEqualWithArrayValue(asiaCity1, asiaCity2)); assertFalse(areEqualWithArrayValue(asiaCity1, asiaCity3)); }
4. Сравнение ключей и значений HashMap
Далее давайте посмотрим, как сравнить два HashMap ключей и их соответствующих значений.
4.1. Сравнение ключей HashMap
Во-первых, мы можем проверить, если два HashMaps имеют те же ключи, просто сравнивая их KeySet () :
@Test public void whenCompareTwoHashMapKeys_thenSuccess() { assertTrue(asiaCapital1.keySet().equals(asiaCapital2.keySet())); assertFalse(asiaCapital1.keySet().equals(asiaCapital3.keySet())); }
4.2. Сравнение значений HashMap
Далее, мы увидим, как сравнить HashMap значения один за другим.
Мы реализуем простой метод проверки того, какие ключи имеют одинаковое значение как в HashMaps с помощью Поток API:
private MapareEqualKeyValues(Map first, Map second) { return first.entrySet().stream() .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue().equals(second.get(e.getKey())))); }
Теперь мы можем использовать areEqualKeyValues () сравнить два разных HashMaps чтобы увидеть в деталях, какие ключи имеют одинаковое значение, а какие имеют разные значения:
@Test public void whenCompareTwoHashMapKeyValuesUsingStreamAPI_thenSuccess() { MapasiaCapital3 = 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. Разница в карте с использованием Гуавы
Наконец, мы увидим как получить подробную разницу между двумя HashMaps с помощью Гуавы Maps.difference().
Этот метод возвращает MapDifference объект, который имеет ряд полезных методов для анализа разницы между Карты. Давайте посмотрим на некоторые из них.
5.1. MapDifference.entriesDiffering()
Во-первых, мы общие ключи, которые имеют различные значения в каждом HashMap с помощью MapDifference.entriesDiffering () :
@Test public void givenDifferentMaps_whenGetDiffUsingGuava_thenSuccess() { Mapasia1 = 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()); }
записиРазумные () метод возвращает новую Карта который содержит набор общих ключей и ЗначениеРазумность объектов как набора значений.
Каждая ЗначениеРазумность объект имеет leftValue () и rightValue () методы, которые возвращают значения в двух Карты соответственно.
5.2. MapDifference.entriesOnlyOnRight() и MapDifference.entriesOnLeft ()
Затем мы можем получить записи, которые существуют только в одном HashMap с помощью MapDifference.entriesOnlyOnRight () и MapDifference.entriesOnlyOnLeft ():
@Test public void givenDifferentMaps_whenGetEntriesOnOneSideUsingGuava_thenSuccess() { MapDifferencediff = 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()
Далее, Мы получим общие записи, используя MapDifference.entriesInCommon():
@Test public void givenDifferentMaps_whenGetCommonEntriesUsingGuava_thenSuccess() { MapDifferencediff = Maps.difference(asia1, asia2); Map entriesInCommon = diff.entriesInCommon(); assertEquals(1, entriesInCommon.size()); assertThat(entriesInCommon, hasEntry("Japan", "Tokyo")); }
5.4. Настройка Maps.difference() Поведение
С Maps.difference () использовать равны () и хэш-код () по умолчанию для сравнения записей, он не будет работать для объектов, которые не реализуют их должным образом:
@Test public void givenSimilarMapsWithArrayValue_whenCompareUsingGuava_thenFail() { MapDifferencediff = Maps.difference(asiaCity1, asiaCity2); assertFalse(diff.areEqual()); }
Но, мы можем настроить метод, используемый в сравнении, используя Эквивалентность .
Например, мы определим Эквивалентность для типа Струнный для сравнения Струнный ценности в нашем HashMaps как нам нравится:
@Test public void givenSimilarMapsWithArrayValue_whenCompareUsingGuavaEquivalence_thenSuccess() { Equivalenceeq = 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. Заключение
В этой статье мы обсудили различные способы сравнения HashMaps на Яве. Мы узнали несколько способов проверить, если два HashMaps равны и как получить подробную разницу, а также.
Полный исходный код доступен более на GitHub .