2012-05-26 55 views
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")工作。我已经尝试调试,我发现它甚至不会输入重写的方法。

我在做什么错?

+2

您的列表包含'Event's,但您正在用字符串调用'contains'。我错过了什么吗? – Tudor

+1

请显示代码,填写列表并调用'contains'。 – Tudor

回答

7

那是因为你打破对称性的equals()specified in the contract:如果任何情况下等于"item"这是一个字符串"item"也应该等于任何事件。

实际上,Java所做的就是在列表中调用indexOf("item"),并检查它是否为正值。

现在,indexOf()作品像这样在ArrayList例如(见complete source code here):

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

所以基本上它是String's equals()方法,在这里叫,不是你一个它返回false当然。

通过简单地指定一个Event参数的功能,如解决这个问题:

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

请注意,你必须为你的类OT初始化成员适当的构造函数。

+0

那我该如何解决呢? – CornflakesDK

+1

最后一个很好的答案。为了完整起见,您可以链接和/或张贴到'ArrayList.contains'的源代码:http://www.docjar.com/html/api/java/util/ArrayList.java.html – Tudor

+1

@CornflakesDK:你可以从比较苹果和橙子开始。在列表中搜索“事件”,因为它包含“事件”。 – Tudor

0

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

了解更多关于这一点:http://www.javapractices.com/topic/TopicAction.do?Id=17

+1

OP只使用'ArrayList'。虽然这个答案是正确的,但这并没有帮助。 –

+1

不,hashCode()对此没有任何处理。这是因为对称性被破坏了。 – rlegendi

0

当你重写equals()方法,你也有,因为他们齐头并进覆盖hashcode()方法。如果两个对象相等,则它们必须具有相同的哈希码。散列图使用它来评估保存位置。如果两个对象不相等,它们可能会或可能不会有相同的哈希码。

0

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

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