3

具有扩展他的Node抽象类。Cell

Cell我实施public boolean equals(Node cmpCell). 我created Set<Node> closeList = new HashSet<Node>();和当我执行时closeList.contains((Cell) node)我调试了它并检测到它完全忽略了Cell equals我实现的。我做错了什么?

编辑 :

Cell我改成

@Override
public boolean equals(Object cmpCell)

并且仍然closeList.contains((Cell) node)没有使用上面的 override 。

第二次编辑:

Cell班上有2名成员-

int colIndex ;
int rowIndex ;

覆盖只是将它们与第二类的equals两个成员进行比较,我认为我使用它会更好,HashMap<K, V>但我仍然很高兴知道hashCode在这种情况下应该是什么样子?

4

4 回答 4

11
public boolean equals(Node cmpCell)

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

public boolean equals(Object)

是的,正如@JonSkeet 在评论中指出的那样,每当你重写equals方法时,还要记住重写hashCode方法以遵循equalsand的合同hashCode。因为如果您不这样做,那么即使您的equals方法显示将您的实例评估为相等,类中的默认hashCode实现Object也会为它们生成different hashCodes,因此它们将不相等。

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

除此之外,如果您使用像Eclipse这样的任何 IDE ,它会为您生成一个非常好的覆盖和兼容equalshashCode方法。你应该更好地使用它们。您需要right-click在课堂上,转到source并选择Generate equals and hashCode method

于 2012-11-25T19:57:29.133 回答
1

您可能没有覆盖hashCode方法。

首先使用哈希码找到哈希集中的对象。您必须始终覆盖这两个equalsandhashCode方法,或者一个都不覆盖。

于 2012-11-25T19:57:29.673 回答
1

那么有三个潜在的问题:

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

  2. 如果你覆盖 equals 你必须实现 hashCode

  3. 您的 equals 方法是否对称(x.equals(y) 意味着 y.equals(x))并且它是否与多态性一起正确发挥作用,即您可以有一个 Node.equals(Cell) 但反过来是错误的吗?

于 2012-11-25T20:03:50.733 回答
0

如前所述,hashCode必须equals相应地实施。

但是这里提出的问题是“为什么不调用自定义的 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);
    }
}
于 2012-11-25T21:21:01.263 回答