Learn different ways to compare two hashmaps in Java by keys, values and key-value pairs. Also, learn to compare Maps while allowing or restricting duplicate values.
1. Compare Maps for Same Keys and Values
1.1. Using Map.equals()
By default, HashMap.equals() method compares two hashmaps by key-value pairs. It means both HashMap instances must have exactly the same key-value pairs and both must be of the same size. The order of key-value pairs can be different and does not play in role in comparison.
Map<String, Integer> map1 = Map.of("A", 1, "B", 2);
Map<String, Integer> map2 = Map.of("A", 1, "B", 2);
Map<String, Integer> map3 = Map.of("C", 1, "D", 2);
Assertions.assertTrue( map1.equals(map2) );
Assertions.assertFalse( map1.equals(map3) );
1.2. Comparing Maps with Array Type Values
It is worth noting the Map keys and values are compared using their equals() method so the key and value objects must properly implement the equals() method to give a consistent result. For example, if Map value is an array then the comparison will not work as array.equals() compares object identity and not the contents of the array.
Map<String, Integer[]> map4 = Map.of("A", new Integer[]{1}, "B", new Integer[]{2});
Map<String, Integer[]> map5 = Map.of("A", new Integer[]{1}, "B", new Integer[]{2});
Assertions.assertFalse(map4.equals(map5));
In such a case, we can create a custom method to compare the array contents using the Arrays.equals() method.
private static boolean checkEqualMapsWithArrayTypeValues(
Map<String, Integer[]> firstMap,
Map<String, Integer[]> secondMap) {
if (firstMap.size() != secondMap.size())
return false;
return firstMap.entrySet().stream()
.allMatch(e -> Arrays.equals(e.getValue(), secondMap.get(e.getKey())));
}
Now the map comparison will check for array content and gives the correct result.
Map<String, Integer[]> map4 = Map.of("A", new Integer[]{1}, "B", new Integer[]{2});
Map<String, Integer[]> map5 = Map.of("A", new Integer[]{1}, "B", new Integer[]{2});
Assertions.assertFalse( checkEqualMapsWithArrayTypeValues(map4, map5) );
2. Comparing Map Keys
We can compare two Maps to have the same keys or not. Or we can find the missing keys in the second Map, if needed.
2.1. Both Maps Have Same Keys
If we want to compare hashmaps by keys i.e. two hashmaps will be equal if they have the exactly the same set of keys, we can use HashMap.keySet() function. It returns all the map keys in HashSet.
Then we can compare the HashSet for both maps using Set.equals() method. It returns true
if the two sets have the same size, and every element of the specified set is contained in another set.
Map<String, Integer> map1 = Map.of("A", 1, "B", 2);
Map<String, Integer> map2 = Map.of("A", 1, "B", 2);
Assertions.assertTrue( map1.keySet().equals(map2.keySet()) );
Map<String, Integer> map3 = Map.of("A", 1, "B", 2, "C", 3, "D", 4);
Assertions.assertFalse( map1.keySet().equals(map6.keySet()) );
2.2. Difference in Map Keys
We may be interested in finding out what extra keys the first hashmap has than the second hashmap. To get this difference, do a union of keys from both hashmaps, and then remove all keys present in the first hashmap.
Java program to find out the difference between two hashmaps.
HashSet<String> unionKeys = new HashSet<>(map1.keySet());
unionKeys.addAll(map3.keySet());
unionKeys.removeAll(map1.keySet());
Assertions.assertEquals(Set.of("C", "D"), unionKeys );
2. Comparing Map Values
If we want to compare hashmaps by values i.e. two hashmaps will be equal if they have exactly the same set of values. Please note that HashMap allows duplicate values, so decide if you want to compare hashmaps with duplicate or without duplicate values.
3.1. Duplicate Values Are NOT Allowed
Add all values from HashMap.values()
to an ArrayList for both maps. Now compare both array lists for equality.
new ArrayList<>( map1.values() ).equals(new ArrayList<>( map2.values() )); //true
new ArrayList<>( map1.values() ).equals(new ArrayList<>( map3.values() )); //false
3.2. Duplicate Values Are Allowed
If you want to remove duplicate values before comparing the hashmaps, add all values into a HashSet that automatically ignores duplicate values.
new HashSet<>( map1.values() ).equals(new HashSet<>( map2.values() )); //true
new HashSet<>( map1.values() ).equals(new HashSet<>( map3.values() )); //true
4. Map Difference with Guava
If we are interested in finding the difference between two Maps then Guava provides an excellent API Maps.difference().
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
The Map.difference() returns an instance of MapDifference class. By inspecting the MapDifference, we can find the difference in Maps in multiple ways.
MapDifference diff = Maps.difference(map1, map2);
Let us see the API in action using a simple example. Both map1 and map2 have some entries in common, and each map has a few distinct entries.
Map<String, Integer> map1 = Map.of("A", 1, "B", 2, "E", 5, "F", 6);
Map<String, Integer> map2 = Map.of("A", 1, "B", 2, "C", 3, "D", 4);
MapDifference<String, Integer> diff = Maps.difference(map1, map2);
Assertions.assertFalse(diff.areEqual());
Assertions.assertEquals(Map.of("A", 1, "B", 2), diff.entriesInCommon());
Assertions.assertEquals(Map.of("E", 5, "F", 6), diff.entriesOnlyOnLeft());
Assertions.assertEquals(Map.of("C", 3, "D", 4), diff.entriesOnlyOnRight());
5. Conclusion
In this short tutorial, we learned to compare two Maps for the equality of their entries, key and values. We also learned to find the Map differences using the plain Java APIs as well as Guava’s MapDifference API.
Drop me your questions related to comparing hashmaps in Java.
Happy Learning !!
Comments