Java 检查hashCode()相等是否是实现相等(对象obj)的有效方法?
我的Java 检查hashCode()相等是否是实现相等(对象obj)的有效方法?,java,equals,hashcode,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
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());
}
这似乎是一个明显的选择,但我并不经常看到。这对我来说是个好主意,还是我遗漏了什么
另外,我不确定这是否相关,但是hashCode
和equals
方法在生成的类中(显然是它们自己生成的)。我提到这一点的原因是为了强调这样一个事实,即这些方法不会根据需要手动维护。它们位于编译时创建的类中,除非模式基于更改,否则不打算更改它们 有时(尽管很少),散列码会导致冲突;你可能知道这一点
因此,将相等性建立在所比较对象的其他特性的基础上(可能除了哈希代码之外)是一个好主意。这不是一个好主意。虽然两个相等的对象必须具有相同的哈希代码,但事实并非如此:具有相同哈希代码的两个对象可能不相等。作为一个简单的例子,考虑<代码>长。哈希代码返回一个
int
,因此不能用int表示所有可能的long
值。这意味着许多Long
对象不是相等的,而是具有相同的哈希代码。如果如问题所述,您的hashCode
实现确实保证了不相等的对象具有不相等的哈希代码,那么原则上您所做的事情没有错。您的equals
方法正在检查一个等价于equality的属性,因此行为符合预期。不过,您应该重新检查该担保;请记住,无论您多么聪明,您只能在int中存储32位信息,这意味着大多数非平凡对象都必须具有哈希合并
然而,有一些警告。首先是清晰性:如果以这种方式实现
equals
,任何使用代码的人都必须查看hashCode
实现,以找出哪些属性决定了相等性。第二个是速度:如果哈希代码实现比简单地检查相关属性的相等性(包括该计算中的布尔快捷方式)慢得多,那么在equals
函数中重新实现逻辑以避免速度损失可能是值得的。第三个是耦合:以这种方式实现equals
意味着它取决于hashCode
的属性,未来对hashCode
的任何更改都必须保留该属性或将逻辑移到equals
否,哈希用于在集合中分发对象,它们不是独一无二的。例如,集合将使用哈希代码来标识放置对象的bucket。bucket本身是具有类似哈希代码的所有对象的列表。目的是在顺序不重要的查找中提高效率
使用相同的相等属性构建哈希非常重要,以确保两个语义相等的对象最终位于同一个bucket中
编辑
虽然我认为我的回答是准确的(没有人说过其他的话),但它实际上并没有回答我认为是人为的问题,正如下面的评论所承认的那样。如果我犯了错误,请随意否决投票,但也请添加一条评论说明原因。如果且仅当你的反肯定保证成立,那么你可以通过这种方式测试平等性。在一般情况下,你的对立面不成立,平等也得不到保证。特别是,有人可能会重写
hashCode()
方法,使您的反正表达式不再有效。使用比较重要字段的更传统的相等性测试要好得多
您的代码是脆弱的,并且在很大程度上取决于
hashCode()
实现的一个非常特定的属性,该属性不是常规hashCode()
契约的一部分。您始终可以使用不匹配的哈希代码来检测不平等性。使用相等的散列码来假定相等是不好的做法 我认为,如果您能够保证一个完美的hashCode()
实现,那么这就可以了。因此,在您的情况下,这很好,因为您的实现保证不会发生冲突。但是,在一般情况下,可能不应该这样做。“我的hashCode方法确保相等的对象具有相等的hash代码。我的实现还保证反正是真的…”那么就没有问题了<根据所述的公理,代码>等于可以用hashCode
来定义。问题的第一句话:“我的hashCode
方法确保相等的对象具有相等的哈希代码”。所以在这种情况下,它们是独一无二的。我不介意被否决,但我更想知道为什么,这样我就可以了解:)-@user3580294,虽然您的hashCode实现可能是安全的,但正如其他人所指出的,这种做法不会出现在一般情况下。您可能希望阅读Joshua Bloch的《高效Java》以获得最佳实践方法,我以为您是OP!没问题!我们所有人都会遇到这种情况。+1是直接解决OP所做断言的唯一答案(这实际上意味着这个“问题”实际上是“不是问题”)。我会评论这两种方法,并指出它们之间的关系。未来的维护人员可能会增加可能值的数量,导致哈希代码冲突或恐慌,因为依赖不同的哈希代码值是equals实现中的常见错误。@PatriciaShanahan“我的哈希代码方法确保相等的对象具有相等的哈希代码。我的实现还保证反正值为真。”(b)设计决定