Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
213 views
in Technique[技术] by (71.8m points)

dictionary - Efficient way to compare two similar maps in java

Imagine I have two maps:

HashMap<TestClass, Integer> map1, map2;

with TestClass being defined as:

class TestClass {
    int i;

    public TestClass(int i){
        this.i = i;
    }
}

And the following code to fill the maps:

map1.put(new TestClass(1), 1);
map1.put(new TestClass(2), 2);

map2.put(new TestClass(1), 1);
map2.put(new TestClass(2), 2);

I want to write a method that returns true if both maps contain the "same" keys and values. Yes, in above example I could just create a local variable to store the result of the first constructor call and pass it to the second map, but I can't do this in my real application as I want to compare similar objects that do not equal each other per se at least as far as java's implementation of the equals method goes.

My previous implementation (simplified):

if(map1.size() == map2.size()){
    for(String key1 : map1.keySet()){
        if(!map1.get(key1).equals(map2.get(key1))
            return false;
    }
    return true;
} else
    return false;

This works fine for Strings, as they equal each other even if instantiated twice in different positions.

As executing the constructor of TestClass twice returns two different objects though, map2.get(key1) will return null (or throw an exception, not entirely sure) as key1 is not in map2.

To compare both maps I have written the following code (simplified):

if(map1.size() == map2.size()){
    for(TestClass key1 : map1.keySet()){
        boolean foundEqualing = false;
        for (TestClass key2 : map2.keySet()) {
            // Search equaling 
            if (key1.i == key2.i) {
                // Check if corresponding values equal as well
                if (map1.get(key1).equals(map2.get(key2))
                    // Store that a equaling key value pair was found
                    foundEqualing = true;
                // Break if keys equaled each other
                break;
            }
        }
        // Return false if no equaling key was found or if keys equal each other but the corresponding values don't
        if (!foundEqualing)
            return false;
    }
    return true;
} else
    return false;

The issue I have with this code is that it loops through both maps, which seems really inefficient to me. I'm not familiar with the correct notations, but the time the operation takes quadruples if the size of the map doubles, if I'm not mistaken.

Is there a way to more efficiently loop through or filter these maps in another way than writing for loops?

My real world code uses reflection, therefore do not focus too hard on the provided example. The types of the map could be from each and every type (the only thing I know is that they have to implement a certain interface, otherwise they are just ignored).

Edit:

I'm currently thinking about using the stream filter collect syntax, but I've never used that. Is that more efficient anyway or does it just loop over the map internally as well?

question from:https://stackoverflow.com/questions/65859132/efficient-way-to-compare-two-similar-maps-in-java

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I want to write a method that returns true if both maps contain the "same" keys and values.

...

Is there a way to more efficiently loop through or filter these maps in another way than writing for loops?

Simply override the equals and hashCode method in TestClass and compare the maps as follows:

map1.equals(map2);

Given below is an excerpt from AbstractMap#equals:

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. More formally, two maps m1 and m2 represent the same mappings if m1.entrySet().equals(m2.entrySet()). This ensures that the equals method works properly across different implementations of the Map interface.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...