检查hashCode()是否是实现equals(Object obj)的有效方法?

时间:2014-06-23 23:20:13

标签: java equals hashcode

我的hashCode方法确保相等的对象具有相同的哈希码。我的实现也保证了对立是正确的,因为相等的哈希码意味着对象相等。做类似的事情:

   @Override
    public boolean equals(Object obj) {
        if (this == obj) {return true;}
        if (obj == null) {return false;}
        if (getClass() != obj.getClass()) {return false;}
        return (obj.hashCode() == this.hashCode());
    }

似乎是一个明显的选择,但我不经常看到这一点。在我的情况下,这是一个好主意,还是我错过了什么?

另外,我不确定这是否相关,但hashCodeequals方法是在生成的类中(显然是自己生成的)。我之所以提到这一点的原因是为了突出这样一个事实,即每次说法都不会手动维护这些方法。它们位于编译时创建的类中,除非基于它们的架构发生更改,否则不打算进行更改。

5 个答案:

答案 0 :(得分:6)

正如问题所说,如果您的hashCode实现确实确保不等对象具有不相等的哈希码,那么原则上您所做的事情没有任何问题。您的equals方法正在检查等同于等同的属性,因此行为符合预期。不过,您应该重新检查该保证;记住,不管你有多聪明,你只能在int中存储32位信息,这意味着大多数非平凡的对象都必须有哈希分数。

然而,有一些警告。首先是清晰度:如果以这种方式实现equals,那么使用您的代码的任何人都必须查看您的hashCode实现,以找出哪些属性确定了相等性。第二是速度:如果您的哈希代码实现明显慢于检查相关属性的相等性(包括该计算中的布尔快捷方式),那么可能值得重新实现equals函数中的逻辑以避免速度惩罚。第三是耦合:以这种方式实现equals意味着它依赖于hashCode的属性,并且对hashCode的任何未来更改都必须保留该属性或将逻辑移动到{{ 1}}。

答案 1 :(得分:4)

这不是一个好主意。虽然两个相等的对象必须具有相同的哈希码,但事实恰恰相反:具有相同哈希码的2个对象可能不相等。举个简单的例子,考虑Long。哈希码返回int,因此无法用int表示所有可能的long值。这意味着许多Long个对象不相等,但具有相同的哈希码。

答案 2 :(得分:2)

如果且仅当您的对立保证成立时,您可以通过这种方式测试平等。在一般情况下,你的对立不存在,并且不保证平等。特别是有人可能会覆盖hashCode()方法,因此您的对立不再成立。更好地使用更传统的平等测试来比较重要的领域。

您的代码很脆弱,并且主要依赖于hashCode()实现的非常具体的属性,该属性不属于一般hashCode()合同。您始终可以使用不匹配的哈希码来检测不等式。使用相等的哈希码来假设相等是不好的做法。

答案 3 :(得分:-1)

有时(虽然很少),哈希码可能导致冲突;你可能已经意识到了这一点!

因此,在被比较的对象的其他特征(可能除了哈希代码之外)上建立相等性是一个好主意。

答案 4 :(得分:-2)

不,哈希用于在集合中分发对象,它们不是唯一的。例如,集合将使用哈希码来标识放置对象的存储桶。存储桶本身是具有类似哈希码的所有对象的列表。目的是提高查找效率,其中顺序不重要。

使用相同的相等属性构建哈希非常重要,以确保2个语义相等的对象最终存在于同一个存储桶中

修改

虽然我认为我的答案是准确的(没有人另有说法),但实际上并没有回答我认为是一个人为的问题,正如下面的评论中所承认的那样。如果我犯了错误,请随意投票,但也请添加评论以说明原因。