contains方法忽略等于覆盖

时间:2012-11-25 19:56:36

标签: java set override equals

拥有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)未使用上述覆盖。

第二次编辑:

Cell课程中有2名成员 -

int colIndex ;
int rowIndex ;

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

4 个答案:

答案 0 :(得分:9)

public boolean equals(Node cmpCell)

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

public boolean equals(Object)

是的,正如@JonSkeet在评论中指出的那样,无论何时覆盖equals方法,还要记得覆盖hashCode方法以遵循equals和{{1}的合同}}。因为如果您不这样做,那么即使您的hashCode方法显示您的实例评估为相等,equals类中的默认hashCode实现也会为它们生成Object ,因此他们不会平等。

另外,请确保在计算different hashCodes时,仅考虑用于在hashcode方法中比较实例的那些属性。否则,你会得到不正确的结果。

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

答案 1 :(得分:1)

您可能没有覆盖hashCode方法。

首先使用哈希码找到哈希集中的对象。您必须始终覆盖两种equalshashCode方法中的两种方法。

答案 2 :(得分:1)

有三个潜在的问题:

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

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

  3. 你的equals方法是否对称(x.equals(y)意味着y.equals(x))并且它是否与多态性一起正确播放,即你是否有一个Node.equals(Cell)但反之则为false

答案 3 :(得分:0)

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

但这里提出的问题是“为什么不调用自定义equals()?”。所以答案是,Java不支持 multiple dispatch

简单示例

如果您声明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);
    }
}