简体   繁体   English

覆盖equals方法不起作用

[英]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. 我试图在ArrayList<Event> events使用此类,但我找不到使events.contains("item")工作的方法。 I have tried debuging and I've found that it doesn't even enter the overridden method. 我试过debuging,我发现它甚至没有进入被覆盖的方法。

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. 那是因为你打破了equals() 合约指定的对称性:如果任何事件等于"item"这是一个String ), "item"也应该等于任何事件。

Actually, what Java does is to call indexOf("item") on your list, and check if it is positive. 实际上,Java所做的是在列表中调用indexOf("item") ,并检查它是否为正数。

Now, indexOf() works like this in an ArrayList for instance (see complete source code here ): 现在, indexOf()ArrayList就像这样工作(参见这里的完整源代码 ):

    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. 所以基本上是这里调用的String的equals()方法,而不是你当然返回false的方法。

Solve this issue by simply specifying an Event parameter to the function, like: 只需为函数指定一个Event参数即可解决此问题,例如:

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() . 您还应该覆盖public int hashCode() The two methods are closely related. 这两种方法密切相关。

Read more about this: http://www.javapractices.com/topic/TopicAction.do?Id=17 阅读更多相关信息: 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. 当您重写equals()方法时,您还必须重写hashcode()方法,因为它们齐头并进。 If two object are equal, then they have to have the same hashcode. 如果两个对象相等,则它们必须具有相同的哈希码。 Hashmaps use this to evaluate the save locations. Hashmaps使用它来评估保存位置。 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. 在这种情况下,您只需要覆盖equals方法,而不是hashCode方法。

The hashCode and equals method should both be overrided when you want to use the object of your class as key in HashMap. 当您想要将类的对象用作HashMap中的键时,应该重写hashCode和equals方法。 HashMap uses a structure of array + linkedList. HashMap使用array + linkedList的结构。 When adding a key-value pair, it first do some calculation based on key's hashCode to get the index in array; 添加键值对时,首先根据键的hashCode进行一些计算,得到数组中的索引; then go throught the linkedList at that index position to find if the key-value pair is already there. 然后遍历该索引位置的linkedList,以查找键值对是否已存在。 If yes, it will overwrite the record with new value; 如果是,它将用新值覆盖记录; otherwise add the key-value pair to the end of that linkedList. 否则将键值对添加到该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. 因此,如果未覆盖hashCode方法,则将无法在数组中进行第一轮搜索。 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. 这不是说某个地方说这两种方法之间存在契约,或者它们之间存在密切关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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