Java equal() 和 hashCode() 基于不同的字段?
是否有任何情况表明,一个类使用一组不同的类字段来实现它的和方法是有意义的?equals()
hashCode()
我之所以这么问,是因为我对 Netbeans 和生成器感到困惑,它们要求您分别选择要包含在每种方法中的字段。我总是最终为这两种方法选择相同的字段,但是是否存在这不是正确选择的情况?equals()
hashCode()
是否有任何情况表明,一个类使用一组不同的类字段来实现它的和方法是有意义的?equals()
hashCode()
我之所以这么问,是因为我对 Netbeans 和生成器感到困惑,它们要求您分别选择要包含在每种方法中的字段。我总是最终为这两种方法选择相同的字段,但是是否存在这不是正确选择的情况?equals()
hashCode()
好吧,必须使用 使用的所有字段,否则您可以为相等的对象获取不同的哈希代码。但事实并非如此 - 您可以选择在选择哈希代码时不考虑某个特定字段。这样,对于两个不相等的对象,您最终可能会得到相同的哈希代码,这两个对象只有“未使用”字段(而不是通过自然碰撞)的差异。你只希望在你知道不太可能发生碰撞的情况下,但你会进行大量的哈希处理。我想这是非常罕见的:)equals()
hashCode()
另一种情况是,您有某种自定义相等比较 - 例如不区分大小写的字符串比较 - 其中为字段生成哈希代码很棘手或昂贵。同样,这将导致碰撞的可能性更大,但会有效。
Jon Skeet在回答这个问题方面做得很好(一如既往)。但是,我想补充一点,对于任何 equals 的实现,这都是一个有效的实现。
public int hashCode() {
return 42;
}
当然,散列数据结构的性能将急剧下降。尽管如此,杀死性能比破坏它们要好。因此,如果您决定覆盖相等,但认为没有必要提供合理的哈希代码实现,那就是懒惰的人要走的路。