5

我在这里和其他网站上浏览了很多类似的问题。我似乎仍然无法解决这个问题。

我有一堂课:

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

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

我正在尝试使用此类,ArrayList<Event> events但找不到events.contains("item")上班的方法。我试过调试,我发现它甚至没有进入被覆盖的方法。

我究竟做错了什么?

4

4 回答 4

7

那是因为你打破了合同中规定的对称性equals():如果任何事件等于"item"它是一个字符串),"item"也应该等于任何事件。

实际上,Java 所做的就是调用indexOf("item")你的列表,并检查它是否是肯定的。

现在,例如,indexOf()像这样工作ArrayList(请参阅此处的完整源代码):

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

所以基本上这里调用的是String 的 equals()方法,而不是你的返回 false 的方法。

只需为函数指定一个Event参数即可解决此问题,例如:

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

请注意,您必须为您的类创建一个适当的构造函数来初始化成员。

于 2012-05-26T10:19:47.367 回答
0

您还应该覆盖public int hashCode(). 这两种方法密切相关。

阅读更多相关信息:http ://www.javapractices.com/topic/TopicAction.do?Id=17

于 2012-05-26T10:15:45.843 回答
0

当您覆盖equals()方法时,您还必须覆盖该hashcode()方法,因为它们是齐头并进的。如果两个对象相等,那么它们必须具有相同的哈希码。Hashmaps 使用它来评估保存位置。如果两个对象不相等,它们可能具有也可能不具有相同的哈希码。

于 2012-05-26T10:16:08.120 回答
0

在这种情况下,您只需要覆盖 equals 方法,而不是 hashCode 方法。

当你想使用你的类的对象作为 HashMap 中的键时,hashCode 和 equals 方法都应该被覆盖。HashMap 使用数组+linkedList 的结构。添加键值对时,首先根据key的hashCode进行计算,得到数组中的索引;然后遍历该索引位置的linkedList,以查找键值对是否已经存在。如果是,它将用新值覆盖记录;否则将键值对添加到该链接列表的末尾。定位密钥时,过程类似。所以如果 hashCode 方法没有被覆盖,你会在数组中的第一轮搜索失败。这就是您需要覆盖这两种方法的原因。不像某处说这两种方法之间有契约或者它们有密切的关系。

于 2014-05-02T20:46:58.667 回答