当前位置: 首页 > 知识库问答 >
问题:

为什么是对象的实现。equals()不使用hashCode()?

姬旭
2023-03-14

或者“为什么Sun/Oracle的家伙每次都强迫我们重写equals()和hashCode()?”

每个人都知道,如果你覆盖一个对象的equals()或hashCode(),你也必须覆盖另一个,因为这两者之间有一个约定:

请注意,每当重写hashCode方法[e.equals()]时,通常有必要重写该方法,以维护hashCode方法的一般约定,即相等的对象必须具有相等的哈希代码。-对象的API文档。等于

为什么不在对象类中以这种方式实现:

public boolean equals(Object obj) {
    return this.hashCode() == obj.hashCode()
}

如果他们这样做了,世界其他地方就不必实施这两种方法了。只重写hashCode()就足够了。

我想他们有充分的理由不这么做。我就是看不见,请帮我把这个弄清楚。

共有3个答案

呼延景同
2023-03-14

有无限多的对象具有相同的哈希代码。这意味着不能单独比较hashCde。

一个简单的例子是Long。hashCode():每个Long值是1L的倍数

酆乐湛
2023-03-14

约阿希姆是正确的,但还有另一个原因:效率。

计算哈希代码可能很昂贵,如果调用了equals(),但从来没有调用过hashCode(),则会产生不必要的工作。

在很多情况下都会出现这种情况;只有像Hashtable(或使用它的类)这样的类才能调用hashCode()

易祯
2023-03-14

如果a.equals(b)返回true,那么a.hashCode()==b.hashCode()必须计算为true

事实并非如此!如果有两个对象,其中a.hashCode()==b.hashCode()为true,但a.equals(b)为false,这是完全有效的。

事实上,这是必要的。有232可能的返回值为hashCode()。在任何给定的时刻,JVM都可以容纳超过2个32对象(如果有足够的内存,现在很有可能)。假设没有一个对象彼此相等(很容易做到,只要让它们是"s1""s2",...),那么你肯定会有校验和的冲突(参见Pidgeonole原理)。

事实上,这是最简单的hashCode实现,对于每个类都是正确的(但在其他方面非常糟糕)*

public int hashCode() {
  return 0;
}

它神奇地满足了通用hashCode()合同的所有要求。

*除了那些必须实现定义并记录了hashCode算法的类,主要示例字符串。hashCode()

 类似资料:
  • 问题内容: 你知道吗 : 将输出: 这是由于(继承自)未覆盖的事实引起的。 您知道为什么会这样吗? 问题答案: 根据的合同,没有针对s 的通用equals()方法,因此无法提供一个。 请注意,它既不是Set也不是List,因此既不是数量也不是它不支持的原因。

  • 问题内容: 无论是Javadoc还是代码本身,Comparator接口都定义了: 但这没有编译任何概率: 但这确实是: 接口不允许用户重写方法的方法是什么? 问题答案: 首先,JavaDocs清楚地解释了您应该实现此方法: 此外,仅当指定对象也是一个比较器并且施加与该比较器相同的顺序时,此方法才能返回true。因此,意味着对于每个对象引用和。 但后来: 请注意,始终不要覆盖即可。 即使它是接口的一

  • 问题内容: 我发现Java 的根类方法没有实现: 如果我有一个and an ,如何不使用就知道the 和value ?只需执行即可。 我尝试了两个对象,但令我大吃惊的是值是相同的:它们都是1。 问题答案: 是一种方法,意味着系统库在内部被调用。有关更多详细信息,请参见Java本机接口。

  • 问题内容: 对于Java的处理方式以及涉及到的数字和其他类型的数字,我有些困惑。例如: 输出(也许您应该先猜测一下): 这不能编译是可以预料的,是不同的对象。 令我有些惊讶的是,默认情况下9是an ,并且1)甚至没有编译。请注意,您不能将放入期望使用的方法中,但是在这里它们是相等的。 由于两个相同的原因,这令人惊讶,但似乎更糟。 不足为奇,因为自动装箱到和。 不足为奇,因为不同类中的对象不应该是。

  • 问题内容: 决定将这些方法包含在java.lang.Object中的背后原因是什么?平等和哈希对于许多类没有意义。 建立两个接口将更加合乎逻辑: 例如,HashSet定义可能看起来像 这将防止出现一个常见的初学者错误-使用项目集而不实现equals / hashCode。 问题答案: 当我们实现一个接口时,我们注入(或接受)该接口定义的合同。 &是两个不同的合同。但是,如果我们仔细观察,就会发现它

  • 问题内容: 伙计们,请让我知道,在现实世界中,为什么我们需要重写equals和hashcode而不能使用Object的equals和hashcode。 问题答案: 对象的equals / hashcode实现很好-如果您希望“引用身份”作为相等性。换句话说,一个对象总是会比较等于自己,但不同于另一个对象。 但是,如果希望两个不同的对象相等,则必须重写该方法以 说明 它们应 如何 相等(然后重写哈希