【发布时间】:2021-08-13 19:05:16
【问题描述】:
我有一个方法可以将一个对象保存在一个以String为键的哈希映射(用作缓存)中。
在方法中传递的对象要么具有“易失性”字段,即它们可以在数据存储的下一次刷新时更改,要么在所有对象中都相同,除了 3 个字段。
这些字段是double 类型的2 个字段和String 类型的1 个字段。
我现在正在做的是我使用:
Objects.hash(doubleField1, doubleField2, theString)
并将结果转换为String。
基本上我是根据不可变状态为该对象生成一个密钥。
这似乎可行,但我有以下问题:
如果我们排除我们有 2 个具有完全相同字段的对象的情况(这是不可能的),我最终会发生无法正确验证的冲突的可能性有多大?
我的意思是,如果我有一个带有键的哈希图,例如字符串等如果在 hashCode 上发生冲突,则比较键的实际值以验证它是否是同一个对象而不是冲突。
以我描述的方式使用密钥会在此类验证中产生问题吗?
更新:
如果我有例如使用fullName 和ssn 或dateOfBirth 生成键为Person 和hashCode 的hashmap 如果存在冲突,则hashmap 实现使用equals 来验证它是否是正在搜索的实际对象为。
我想知道我描述的方法是否可能在该部分存在一些问题,因为我直接生成了实际密钥
【问题讨论】:
-
如果您在谈论 hashCode 更改的键,那么这是一个坏主意。键应该是不可变的。如果您在谈论碰撞,那么我认为这应该不是问题。 hashCode 实现可以返回一个像 42 这样的常量。但是这样您的映射将不会非常有效,因为它会退化为一个链表。但我不完全确定您所说的验证是什么意思。
-
HashMap(以及HashSet)不仅通过hashcode()识别对象,还通过equals()识别对象,因此满足Hashcode/Equals contract很重要。 -
@WJS: 1) 密钥不会改变。 2)如果我有,例如使用
fullName和ssn或dateOfBirth生成键为Person和hashCode的hashmap 如果存在冲突,则hashmap 实现使用equals来验证它是否是正在搜索的实际对象为了。我想知道我描述的方法在那部分是否有问题 -
如果您在
HashMap中使用哈希作为键并且发生冲突,则使用相同键存储在HashMap中的第一个对象将丢失。 -
是的。这是一种选择。
标签: java hash hashmap collision-detection hash-collision