简体   繁体   中英

Overriding equals method doesn't work

I've been browsing a lot of similar questions in here and on other sites. Still I can't seem to get my head wrapped around this problem.

I have a class:

public class Event {
    public String Item;
    public String Title;
    public String Desc;

    @Override
    public boolean equals(Object o) {
            return true;
    }
}

I'm trying to use this class in an ArrayList<Event> events but I can't find a way to get events.contains("item") to work. I have tried debuging and I've found that it doesn't even enter the overridden method.

What am I doing wrong?

That's because you're breaking symmetry as specified in the contract of equals() : if any event equals to "item" ( which is a String ), "item" should also be equal to any event.

Actually, what Java does is to call indexOf("item") on your list, and check if it is positive.

Now, indexOf() works like this in an ArrayList for instance (see complete source code here ):

    for (int i = 0; i < size; i++)
        if ("item".equals(elementData[i]))
            return i;

So basically it is the String's equals() method which is called here, not your one which is returning false of course.

Solve this issue by simply specifying an Event parameter to the function, like:

events.contains( new Event("item", "title", "desc") )

Note that you'll have to create a proper constructor for your class ot initialize the members.

You should also override public int hashCode() . The two methods are closely related.

Read more about this: http://www.javapractices.com/topic/TopicAction.do?Id=17

When you override equals() method, you also have to override the hashcode() method because they go hand in hand. If two object are equal, then they have to have the same hashcode. Hashmaps use this to evaluate the save locations. If two objects are not equal, they may or may not have the same hashcode.

In this case, you need only override equals method, not the hashCode method.

The hashCode and equals method should both be overrided when you want to use the object of your class as key in HashMap. HashMap uses a structure of array + linkedList. When adding a key-value pair, it first do some calculation based on key's hashCode to get the index in array; then go throught the linkedList at that index position to find if the key-value pair is already there. If yes, it will overwrite the record with new value; otherwise add the key-value pair to the end of that linkedList. When locating a key, the process is smiliar. So if the hashCode method is not overrided, you will fail the first round search in the array. That's the reason why you need override both methods. It's not like somewhere says there's contract between these two methods or they have close relation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM