Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 检查hashCode()相等是否是实现相等(对象obj)的有效方法?_Java_Equals_Hashcode - Fatal编程技术网

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)设计决定