Membandingkan Dua HashMaps di Java

1. Ikhtisar

Dalam tutorial ini, kita akan menjelajahi berbagai cara untuk membandingkan dua HashMaps di Java .

Kami akan membahas berbagai cara untuk memeriksa apakah dua HashMaps serupa. Kami juga akan menggunakan Java 8 Stream API dan Guava untuk mendapatkan perbedaan mendetail antara HashMaps yang berbeda .

2. Menggunakan Map.equals ()

Pertama, kita akan menggunakan Map.equals () untuk memeriksa apakah dua HashMaps memiliki entri yang sama:

@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)); }

Di sini, kami membuat tiga objek HashMap dan menambahkan entri. Kemudian kami menggunakan Map.equals () untuk memeriksa apakah dua HashMaps memiliki entri yang sama.

Cara Map.equals () bekerja adalah dengan membandingkan kunci dan nilai menggunakan Object.equals () metode . Ini berarti ini hanya berfungsi ketika objek kunci dan nilai mengimplementasikan sama dengan () dengan benar.

Misalnya, Map.equals () tidak berfungsi jika tipe nilainya adalah array, karena metode equals () array membandingkan identitas dan bukan konten dari array:

@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. Menggunakan Java Stream API

Kami juga dapat menerapkan metode kami sendiri untuk membandingkan HashMaps menggunakan Java 8 Stream API:

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()))); }

Untuk kesederhanaan, kami menerapkan metode areEqual () yang sekarang dapat kami gunakan untuk membandingkan objek HashMap :

@Test public void whenCompareTwoHashMapsUsingStreamAPI_thenSuccess() { assertTrue(areEqual(asiaCapital1, asiaCapital2)); assertFalse(areEqual(asiaCapital1, asiaCapital3)); }

Tapi kita juga bisa menyesuaikan metode kita sendiri areEqualWithArrayValue () untuk menangani nilai array dengan menggunakan Arrays.equals () untuk membandingkan dua array:

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()))); }

Tidak seperti Map.equals () , metode kami sendiri akan berhasil membandingkan HashMaps dengan nilai array:

@Test public void whenCompareTwoHashMapsWithArrayValuesUsingStreamAPI_thenSuccess() { assertTrue(areEqualWithArrayValue(asiaCity1, asiaCity2)); assertFalse(areEqualWithArrayValue(asiaCity1, asiaCity3)); }

4. Membandingkan Kunci dan Nilai HashMap

Selanjutnya, mari kita lihat cara membandingkan dua kunci HashMap dan nilainya yang sesuai.

4.1. Membandingkan Kunci HashMap

Pertama, kita dapat memeriksa apakah dua HashMaps memiliki kunci yang sama dengan hanya membandingkan KeySet () :

@Test public void whenCompareTwoHashMapKeys_thenSuccess() { assertTrue(asiaCapital1.keySet().equals(asiaCapital2.keySet())); assertFalse(asiaCapital1.keySet().equals(asiaCapital3.keySet())); }

4.2. Membandingkan Nilai HashMap

Selanjutnya, kita akan melihat bagaimana membandingkan nilai HashMap satu per satu.

Kami akan menerapkan metode sederhana untuk memeriksa kunci mana yang memiliki nilai yang sama di kedua HashMaps menggunakan Stream API:

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())))); }

Sekarang kita dapat menggunakan areEqualKeyValues ​​() untuk membandingkan dua HashMaps yang berbeda untuk melihat secara detail kunci mana yang memiliki nilai yang sama dan yang memiliki nilai berbeda:

@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. Peta Perbedaan Menggunakan Jambu Biji

Terakhir, kita akan melihat bagaimana mendapatkan perbedaan mendetail antara dua HashMaps menggunakan Guava Maps.difference ().

Metode ini mengembalikan objek MapDifference yang memiliki sejumlah metode yang berguna untuk menganalisis perbedaan di antara Maps. Mari kita lihat beberapa di antaranya.

5.1. MapDifference.entriesDiffering ()

Pertama, kita akan mendapatkan kunci umum yang memiliki nilai berbeda di setiap HashMap menggunakan MapDifference.entriesDiffering () :

@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()); }
    

Metode entriesDiffering () mengembalikan Map baru yang berisi kumpulan kunci umum dan objek ValueDifference sebagai kumpulan nilai.

Setiap objek ValueDifference memiliki metode leftValue () dan rightValue () yang mengembalikan nilai masing-masing di dua Maps .

5.2. MapDifference.entriesOnlyOnRight () dan MapDifference.entriesOnlyOnLeft ()

Kemudian, kita bisa mendapatkan entri yang hanya ada di satu HashMap menggunakan MapDifference.entriesOnlyOnRight () dan MapDifference.entriesOnlyOnLeft ():

@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 ()

Selanjutnya, kita akan mendapatkan entri umum menggunakan 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. Menyesuaikan Maps.difference () Behavior

Karena Maps.difference () menggunakan equals () dan hashCode () secara default untuk membandingkan entri, ini tidak akan berfungsi untuk Objek yang tidak mengimplementasikannya dengan benar:

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

Tapi, kita bisa menyesuaikan metode yang digunakan dalam perbandingan menggunakan Equivalence .

Misalnya, kita akan menentukan Ekuivalensi untuk tipe String [] untuk membandingkan nilai String [] di HashMaps kita sesuka kita:

@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. Kesimpulan

Pada artikel ini, kami membahas berbagai cara untuk membandingkan HashMaps di Java. Kami mempelajari berbagai cara untuk memeriksa apakah dua HashMaps sama dan cara mendapatkan perbedaan mendetail juga.

Kode sumber lengkap tersedia di GitHub.