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

如果将constant返回到hashcode而将false返回到equals会发生什么

翟奇逸
2023-03-14

hashcode或hashmap是如何工作的,如果我们重写hashcode返回的总是常量,而重写的equals方法返回false,它如何能够在返回或删除时识别准确的对象?时间bean忘记了性能所有的东西,我的问题是它如何能够识别精确的对象,让我再解释一点,我有一个有两个字段的person类,已经重写了返回总是1的hashcode和重写了返回false的equals方法,已经创建了3个对象,对象1--id 10名称AAAA,对象2--id 20,名称BBB,对象3--id 30,名称CCC,我已经将所有这三个对象添加到hashSet,之后我删除了对象2,这里它如何识别精确的对象(20,BBB)

共有1个答案

潘琨
2023-03-14

嗯,常量hashcode是有效的,并且在使用hashmap/hashset或其他使用它来优化比较/搜索的代码时“只是”一个性能问题。

但是,始终返回falseequals()实现违反了equals的约定,并将导致许多类型的集合出现问题/出现令人惊讶的行为。

equals的JavaDocs中:

equals方法在非空对象引用上实现等价关系:

  • 它是自反的:对于任何非空引用值x,x.equals(x)应返回true。
  • 它是对称的:对于任何非空引用值x和y,x.equals(y)应返回true当且仅当y.equals(x)返回true。
  • 它是可传递的:对于任何非空引用值x、y和z,如果x.equals(y)返回true,而y.equals(z)返回true,则x.equals(z)应返回true。
  • 一致性:对于任何非空引用值x和y,x.equals(y)的多次调用一致地返回true或一致地返回false,前提是对象上的equals比较中使用的信息未被修改。
  • 对于任何非空引用值x,x.equals(null)应返回false。

returnfalse实现违反了第一个要求。

  • 如果根据equals(java.lang.Object)方法,两个对象不相等,那么对两个对象中的每一个调用hashCode方法就必须产生不同的整数结果,这并不是一个要求。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

正如@mensur Qulami在评论中指出的,如果您的实现使用与==的引用比较来优化对节点的搜索,则hashmap仍然可以正常工作。

从OpenJDK 12 hashmap.getNode(int hash,对象键):

((k=first.key)==key(key!=null&&key.equals(k)))

因此,此实现在尝试equals()之前检查引用相等性,但这并不保证。

hashmap.get的JavaDocs通过equals()严格定义了这一点

更正式地说,如果此映射包含从键k到值v的映射,使得(key==null?k==null:key.equals(k)),则此方法返回v;否则返回null

(如果equals的实现履行了上面的约定,那么这是等价的,因此OpenJDK所做的优化是有效的)

 类似资料:
  • 问题内容: 我正在创建一个需要实施的游戏。在游戏过程中,我想在特定时间内暂停监听器。我尝试从方法返回false ,但方法仍然保持执行状态。还有其他方法可以让监听器暂停一段时间吗?任何人都请解释一下从错误返回的实际含义是什么? 问题答案: 从View文档中: 如果您返回,则告诉android媒体已经处理完毕。算了吧。 如果您返回,则基本上会说“不是我的问题,请其他人来处理此点击”。然后android

  • 问题内容: 我正在使用一个调用python脚本的VBA代码。我可以将参数发送到python脚本并使用读取。 在python代码中,我有一个函数,该函数接受给定的参数并返回一个值。 请问如何在VBA中获得返回值? 问题答案: 考虑使用VBA Shell捕获输出线流。确保打印Python脚本以筛选值: 蟒蛇 VBA (下面是字符串输出)

  • 我正在Java开发一个纸牌游戏,我试图比较hashMap中的键和ArrayList中的元素(两者都是对象)。hashCode()和equals()被重写,但出现了一个错误,我不确定它的哪一部分是错误的。 这是纸牌课 我们要做的比较 错误:点击查看错误图片

  • 问题内容: 据我所知,使用或实例化对象分别返回或的新实例。具有 新标识 的新实例对象。 在我实际测试它之前,这对我来说是很清楚的,我注意到它实际上返回了而不是预期的: 如预期的那样,分别使用和创建对象时,也会表现出这种行为: 我可以在状态文档中找到唯一相关的信息: […]例如,return和return 。 如果未提供任何参数,则构造函数将创建一个新的空元组。 可以说,这不足以回答我的问题。 那么

  • 而且 不是应该都返回吗?它不是基元变量,在第二个代码中,即使在添加零之后,它也会打印。我知道装箱(对于从-128到127的整数),但是为什么装箱在第二段代码中起作用而不是在第一段代码中起作用呢?

  • 我像这样初始化哈希集: 我的对象(抽象类的子类)的和方法如下所示: 我甚至编写了一个简单的单元测试,它不会给出任何错误: 在我的应用程序中,我有一个方法,我只需将对象添加到: 在另一种方法中,我检查