0

I understood that you can pass pretty much anything to a method with an object. I am trying to write an assert function that checks whether two maps are equal. I can't just use map1.equals(map2) because even if they have all the same keys and values, they might be in a different order. So I wanted to go througheach key in the first map and get its value and compare it to the value for that key in the second map. And I wanted to do it generically. So I wrote this (which is sort of a stub to demonstrate my question. I will do more null checking, etc):

public void assertMapEquals( Map<Object, Object> f, Map<Object, Object> l) {

    // This will do null checks, don't worry
    for ( Entry<Object, Object> ent : f.entrySet()) {       
        if (f.size() != l.size()) {
            throw new AssertionError ("size mismatch");
        }       
        Object k = ent.getKey();
        Object e = ent.getValue();
        Object a = l.get(k);        
        if (!e.equals(a)) {
            throw new AssertionError( "unequal");
        }       
    }
}

Then I try to call it with two String maps:

public static void main(String[] argv) throws SQLException {

    Map<String,String> m1 = new HashMap<>();
    Map<String,String> m2 = new HashMap<>();
    // Data will get filled in later
    assertMapEquals(m1, m2);
    // ...
 }

but Eclipse is giving me the following error on the call:

The method assertMapEquals(Map, Map) in the type MyMain1 is not applicable for the arguments (Map, Map)

Aren't strings objects, so why won't this work, and what should I do? This question can apply to any example of this sort, not just comparing two maps.

An additional question I would have is is there a better way I can do this where it compares but does not care about the order?

9
  • Why don't you use assertMapEquals(Map<String,String>, Map<String,String>) ? Commented Mar 3, 2016 at 12:51
  • That is what I changed it to, but it is conceiveable I would want to call it sometimes with other types of maps. Commented Mar 3, 2016 at 12:57
  • Ordering is only guaranteed if you are using TreeMap. Any other Map does not preserve ordering of the keys Commented Mar 3, 2016 at 13:01
  • 1
    why do you check for f.size() != l.size() on each iteration? this check should be done outside the foreach. Commented Mar 3, 2016 at 13:02
  • 1
    I don't follow your reason for not using AbstractMap.equals(). From the JavaDoc for AbstractMap - "More formally, two maps m1 and m2 represent the same mappings if m1.entrySet().equals(m2.entrySet())". That should be order independent and sounds exactly like what you're trying to implement. Commented Mar 3, 2016 at 13:05

1 Answer 1

2

You may use generic method paramethized by <?, ?> (not <K, V>, because as mentioned in comments they may be of different type and still equal, e. g. Map<String, String> vs Map<Object, Object>):

public static void assertMapEquals(Map<?, ?> f, Map<?, ?> l) {
    if (f == null || l == null)
         throw new NullPointerException();
    if (f.size() != l.size()) 
            throw new AssertionError ("size mismatch");
    for (Entry<?, ?> ent : f.entrySet()) {            
        Object k = ent.getKey();
        Object e = ent.getValue();
        Object a = l.get(k);        
        if (!Objects.equals(e, a))      // handle null values
            throw new AssertionError("unequal");
    }
}

The other approach will be just directly compare maps:

public static void assertMapEquals(Map<?, ?> f, Map<?, ?> l) {
     if (f == null || l == null)
         throw new NullPointerException();
     if (f.size() != l.size())
         throw new AssertionError("size mismatch");
     if (!f.equals(l))
         throw new AssertionError("unequal contents");
}

By contract, Map#equals(Object o) returns true iff o is Map which has equal contents.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.