包含方法忽略了equals覆盖

3

有一个抽象类NodeCell是他的子类。

Cell中,我实现了public boolean equals(Node cmpCell)。我创建了一个Set<Node> closeList = new HashSet<Node>(),当我执行closeList.contains((Cell) node)时,我进行了调试,发现它完全忽略了我所实现的Cell equals。我做错了什么?

编辑:

我在Cell中进行了更改

@Override
public boolean equals(Object cmpCell)

而且closeList.contains((Cell) node)仍然没有使用上述覆盖。

第二次编辑:

Cell类中有2个成员 -

int colIndex ;
int rowIndex ;

equals方法只是比较第二个类的两个成员变量是否相等,因此我认为最好使用HashMap<K, V>。但是,我仍然很想知道在这种情况下hashCode应该长什么样。

4个回答

11
public boolean equals(Node cmpCell)

这不是一个有效的覆盖。Object类的equals方法的语法是:

public boolean equals(Object)

是的,正如@JonSkeet在评论中指出的那样,每当您重写equals方法时,也应记得重写hashCode方法以遵循equalshashCode的协定。因为如果您不这样做,即使您的equals方法显示将实例视为相等,Object类中默认的hashCode实现将为它们生成不同的哈希码,因此它们将不相等。

此外,在计算hashcode时,请确保仅考虑您在equals方法中用于比较实例的属性。否则,您将再次获得不正确的结果。

除此之外,如果您使用像Eclipse这样的IDE,它会为您生成非常好的重写和兼容的equalshashCode方法。您最好使用它们。 您需要右键单击您的类,转到源代码并选择生成equals和hashCode方法


1
这就是为什么@Override应该总是注释一个方法,该方法应该覆盖另一个方法。如果没有这样做,就会导致编译错误。 - JB Nizet
@URL87.. 请阅读我的编辑答案。您还需要覆盖hashCode方法。您是否使用Eclipse IDE?如果是,则请遵循我的最后一段话。 - Rohit Jain
@URL87.. 你不是在使用 Eclipse IDE 吗? - Rohit Jain

1

你可能没有覆盖hashCode方法。

哈希集合中的对象首先使用哈希码进行查找。您必须始终覆盖两个equalshashCode方法,或者都不覆盖。


2
这肯定可以是答案的一部分。OP 需要覆盖 hashCode() 和 equals(Object) 两个方法。 - Jon Skeet
@dystroy,您能否按照编辑中的类演示hashCode? - URL87

1

可能有三个潜在的问题:

  1. 您覆盖了错误的签名。应该是 public boolean equals(Object)

  2. 如果您重写了equals方法,则必须实现hashCode方法

  3. 您的equals方法是否对称(x.equals(y)意味着y.equals(x)),并且它是否正确地与多态性一起使用,即您可以拥有Node.equals(Cell),但反过来却是false?


0

如前所述,必须相应地实现hashCodeequals

但这里提出的问题是“为什么不调用自定义equals()方法?”。因此,答案是Java不支持多重分派

简单示例

如果您声明Object myCell = new Cell(),那么myCell2.equals(myCell)只能确定myCell的声明类型,即Object

您的情况

被调用方法的签名是:HashSet.contains(Object o),具有与上述相同的后果。

您可以做类似于以下的事情,尽管这不是一个好的解决方案:

public class Cell {
    @Override
    public boolean equals(Object o) {
        if(o instanceof Cell) {
            // your code
        }

        super.equals(o);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接