我在这里和其他网站上一直在浏览很多类似的问题。我似乎无法解决这个问题。
我有一个班级:
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")
工作的方法。我尝试过调试,我发现它甚至没有进入被覆盖的方法。
我做错了什么?
答案 0 :(得分:7)
那是因为你打破了equals()
specified in the contract的对称性:如果任何事件等于"item"
(是一个字符串),{{1也应该等于任何事件。
实际上,Java所做的就是在列表中调用"item"
,并检查它是否为正。
现在,indexOf("item")
在indexOf()
中就像这样工作(参见complete source code here):
ArrayList
所以基本上这是在这里调用的String's equals()方法,而不是当然会返回false的方法。
只需为函数指定 for (int i = 0; i < size; i++)
if ("item".equals(elementData[i]))
return i;
参数即可解决此问题,例如:
Event
请注意,您必须为您的类创建一个正确的构造函数,或者初始化成员。
答案 1 :(得分:0)
您还应该覆盖public int hashCode()
。这两种方法密切相关。
详细了解:http://www.javapractices.com/topic/TopicAction.do?Id=17
答案 2 :(得分:0)
当您覆盖equals()
方法时,您还必须覆盖hashcode()
方法,因为它们齐头并进。如果两个对象相等,则它们必须具有相同的哈希码。 Hashmaps使用它来评估保存位置。如果两个对象不相等,则它们可能具有相同的哈希码,也可能不具有相同的哈希码。
答案 3 :(得分:0)
在这种情况下,您只需要覆盖equals方法,而不是hashCode方法。
当您希望将类的对象用作HashMap中的键时,应该重写hashCode和equals方法。 HashMap使用array + linkedList的结构。添加键值对时,首先根据键的hashCode进行一些计算,得到数组中的索引;然后遍历该索引位置的linkedList,以查找键值对是否已存在。如果是,它将用新值覆盖记录;否则将键值对添加到该linkedList的末尾。找到密钥时,过程很熟悉。因此,如果未覆盖hashCode方法,则将无法在数组中进行第一轮搜索。这就是你需要覆盖这两种方法的原因。它不像某个地方说这两种方法之间存在合同,或者它们有密切关系。