java - 如果将常量返回到哈希码并且返回 false 到 equals 会发生什么
问题描述
hashcode 或 hashmap 是如何工作的,如果我们重写 hashcode,它总是返回一个常量,而重写的 equals 方法返回 false,它如何在返回或删除时识别确切的对象?time bean 忘记了所有这些东西的性能,我的问题是它如何识别确切的对象,让我再解释一下,我有一个带有两个字段的 person 类,并且覆盖了始终返回 1 的哈希码和覆盖了返回 false 的 equals 方法,创建了 3 个对象,对象 1 - id 10 名称 AAAA,对象 2 - id 20,名称 BBB,对象 3 - id 30,名称 CCC,我已将所有三个对象添加到 hashSet,之后我删除了对象2、这里如何识别它的确切对象(20、BBB)
解决方案
HashMap
好吧,当使用/HashSet
或其他使用它来优化比较/搜索的代码时,常量哈希码是有效的并且“只是”一个性能问题。
equals()
然而,总是返回的实现false
会破坏 equals 的约定,并会导致许多类型的集合出现问题/令人惊讶的行为。
equals 方法在非空对象引用上实现等价关系:
- 它是自反的:对于任何非空引用值 x,x.equals(x) 应该返回 true。
- 它是对称的:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应该返回 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。
一个return false
实现打破了第一个要求。
- 如果根据 equals(java.lang.Object) 方法,如果两个对象不相等,则不需要对两个对象中的每一个调用 hashCode 方法都必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
正如 @Mensur QulamiHashMap
在评论中指出的那样,如果您的实现使用参考比较==
来优化节点搜索,它可能仍然可以正常工作。
从OpenJDK 12 HashMap.getNode(int hash, Object key):
((k = first.key) == key || (key != null && key.equals(k))))
所以这个实现在尝试之前检查引用相等equals()
,但这不能保证。
JavaDocs 严格按照以下HashMap.get
方式定义equals()
更正式地说,如果此映射包含从键 k 到值 v 的映射
(key==null ? k==null : key.equals(k))
,则此方法返回v
; 否则返回null
。
(如果的实现equals
符合上述约定,则等效,因此 OpenJDK 所做的优化是有效的)
推荐阅读
- json - Json反序列化Vb中的嵌套对象(Newtonsoft)
- pytorch - 自定义 LSTM 单元实现
- javascript - 如果javascript中的模式匹配,如何在按钮单击时显示内容?
- python - 需要在 Queryset 中获取一对多模型,以便 Queryset 具有重复的相同记录,每个子/嵌套模型一个
- javascript - React Redux 无法传递功能组件的 props
- python - 使用指定的 CA 密钥和 paramiko 签署公钥
- bash - 获取 Git 分支的跟踪信息
- json - 对 JSON 数据的 SQL 查询
- python - 将列表传递给 sklearn - accuracy_score 进行评分
- jpa - 父 ID 未填充到子对象中 - JPA