46

How can I best compare two HashMaps, if I want to find out if none of them contains different keys than the other, and if the values of that keys match each other.

Map<objA, objB> mapA = new HashMap<objA, objB>();
mapA.put("A", "1");
mapA.put("B", "2");

Map<objA, objB> mapB = new HashMap<objA, objB>();
mapB.put("D", "4");
mapB.put("A", "1");

When comparing A with B, it should fail due to different keys B and D.

How could I best compare non-sorted hashmaps?

Anchit
  • 171
  • 1
  • 11
membersound
  • 81,582
  • 193
  • 585
  • 1,120

7 Answers7

74

Simply use :

mapA.equals(mapB);

Compares the specified object with this map for equality. Returns true if the given object is also a map and the two maps represent the same mappings

user2336315
  • 15,697
  • 10
  • 46
  • 64
  • Is this for Java or Android? On Android, the description for `equals` is [different](http://stackoverflow.com/a/29431623/145173). – Edward Brey Apr 03 '15 at 11:50
  • @EdwardBrey The description you state does the same thing. And I don't know where you got this definition because it's the same on the Android doc: http://developer.android.com/reference/java/util/Map.html#equals(java.lang.Object) – user2336315 Apr 03 '15 at 22:32
  • The documentation for the interface method [Map.equals](http://developer.android.com/reference/java/util/Map.html#equals(java.lang.Object)) is as you quoted. However, `HashMap` implements the `equals` method of that interface via [AbstractMap.equals](http://developer.android.com/reference/java/util/AbstractMap.html#equals(java.lang.Object)), which has the weaker guarantee that I quoted. The `AbstractMap` code matches its documentation. It seems to me that `HashMap` violates the contract of the interface. – Edward Brey Apr 03 '15 at 22:54
  • 2
    @EdwardBrey Then tell me the difference between what you quoted? Because I don't see any. It does the same thing... _"This implementation first checks the structure of object. If it is not a map or of a **different size**, this returns false. Otherwise it iterates its **own entry set**, looking up each **entry's key** in **object**. If any **value** does not equal **the other map's value** for the **same** key, this returns false. Otherwise it returns true."_ – user2336315 Apr 08 '15 at 09:10
  • I was concerned that it doesn't say that it iterates over the other entry set and does a lookup the other way. However, since, as you highlighted, it checks for identical size and since keys must be unique in each map, it doesn't need to. A comparison starting from just one side is sufficient. – Edward Brey Apr 08 '15 at 11:54
33

Make an equals check on the keySet() of both HashMaps.

NOTE:

If your Map contains String keys then it is no problem, but if your Map contains objA type keys then you need to make sure that your class objA implements equals().

Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
11

Compare every key in mapB against the counterpart in mapA. Then check if there is any key in mapA not existing in mapB

public boolean mapsAreEqual(Map<String, String> mapA, Map<String, String> mapB) {

    try{
        for (String k : mapB.keySet())
        {
            if (!mapA.get(k).equals(mapB.get(k))) {
                return false;
            }
        } 
        for (String y : mapA.keySet())
        {
            if (!mapB.containsKey(y)) {
                return false;
            }
        } 
    } catch (NullPointerException np) {
        return false;
    }
    return true;
}
Community
  • 1
  • 1
Antonio Ortells
  • 327
  • 2
  • 11
  • This doesn't work if you have null values in your map. Given the following two maps, it will fail the comparison: final Map map1 = new HashMap<>(); map1.put("key1", new Double(0.0)); map1.put("key2", new Double(75.0)); map1.put("key3", null); final Map map2 = new HashMap<>(); map2.put("key1", Double.valueOf("0.0")); map2.put("key2", 75.0); map2.put("key3", null); – Steve Swinsburg Jan 23 '18 at 01:41
3
/* JAVA 8 using streams*/
   public static void main(String args[])
    {
        Map<Integer, Boolean> map = new HashMap<Integer, Boolean>();
        map.put(100, true);
        map.put(1011, false);
        map.put(1022, false);

        Map<Integer, Boolean> map1 = new HashMap<Integer, Boolean>();
        map1.put(100, false);
        map1.put(101, false);
        map1.put(102, false);

        boolean b = map.entrySet().stream().filter(value -> map1.entrySet().stream().anyMatch(value1 -> (value1.getKey() == value.getKey() && value1.getValue() == value.getValue()))).findAny().isPresent();
        System.out.println(b);
    }
0
public boolean compareMap(Map<String, String> map1, Map<String, String> map2) {

    if (map1 == null || map2 == null)
        return false;

    for (String ch1 : map1.keySet()) {
        if (!map1.get(ch1).equalsIgnoreCase(map2.get(ch1)))
            return false;

    }
    for (String ch2 : map2.keySet()) {
        if (!map2.get(ch2).equalsIgnoreCase(map1.get(ch2)))
            return false;

    }

    return true;
}
SanA
  • 119
  • 1
  • 6
0

if you have two maps lets say map1 and map2 then using java8 Streams,we can compare maps using code below.But it is recommended to use equals rather then != or ==

boolean b = map1.entrySet().stream().filter(value -> 
            map2.entrySet().stream().anyMatch(value1 -> 
            (value1.getKey().equals(value.getKey()) && 
  value1.getValue().equals(value.getValue())))).findAny().isPresent();   


System.out.println("comparison  "+b);
Swati
  • 11
  • 4
0

A simple and good algorithm for such a comparison could be:

    Map<Integer, Boolean> map1 = new HashMap<Integer, Boolean>();
    map1.put(100, false);
    map1.put(101, false);
    map1.put(102, false);

    Map<Integer, Boolean> map2 = new HashMap<Integer, Boolean>();
    map2.put(100, false);
    map2.put(1011, false);
    map2.put(1022, false);

    if (!map1.keySet().equals(map2.keySet())) {
        result = false;
    } else {
        result = map1.keySet()
                .stream()
                .allMatch(key -> map1.get(key).equals(map2.get(key)));
    }

Simply you'll have to compare the set of keys, if they are equal, then compare the values for each key on both maps.

Jonas Freire
  • 165
  • 3
  • 4