栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

对象Hashcode更改时,在Hashmap或Hashset中查找会发生什么情况

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

对象Hashcode更改时,在Hashmap或Hashset中查找会发生什么情况

在您的示例中,字符串是不可变的,因此其哈希码无法更改。但是假设,如果某个对象的哈希码确实是一个哈希表中的键而发生了变化,那么就哈希表查找而言,它很
可能会消失
。我在一个相关问题的答案中对此做了更详细的介绍:。(最初的问题是关于a

HashSet
,但a
HashSet
实际上是一个
HashMap
底线,因此答案也涵盖了这种情况。)


为了补充@EJP的答案,如果您将a中的对象突变HashSet以使其重复(在equals/hashpre合同意义上),那么在实践中将会发生的事情是哈希表数据结构将中断。

根据突变的确切细节以及哈希表的状态,一个或两个实例将对查找(例如contains和其他操作)不可见。它要么在错误的哈希链上,要么是因为另一个实例出现在哈希链之前。而且很难预测哪个实例将是可见的……以及它是否仍将保持可见。

如果您对集合进行迭代,则这两个实例仍将存在…违反Set合同。

当然,从应用程序的角度来看,这是非常糟糕的。

您可以通过以下任一方法避免此问题:

为您的设置元素使用不可变的类型,
在将对象放入集合中和/或从集合中拉出对象时进行复制,
编写代码,使其“知道”在持续时间内不更改对象…
从正确性和鲁棒性的角度来看,第一种选择显然是最好的。

顺便说一句,以一般方式“解决”这一问题确实很困难。Java中没有普遍的机制来知道……或被告知……某些元素已更改。您可以在逐个类的基础上实现这种机制,但必须对其进行显式编码(而且价格不菲)。即使您确实有这种机制,您会怎么做?显然,现在应该从集合中删除其中一个对象…但是,哪个对象呢?

它是安全地说,如果任何一个HashMap或映像树的钥匙,影响他们各自的方式突变

hashpre()
/
equals(Object)
compare(...)
compareTo(...)
合同,然后将数据结构“破发”。


这是否意味着一旦将数据放入哈希集中,就不应对其进行更改。

是。

还是需要重新修复?还是自动完成等?

它不会自动修复。该

HashMap
不会注意到一个关键的哈希码已经改变。确实,
HashMap
调整大小后,您甚至都不会重新计算哈希码。数据结构会 记住
原始哈希码值,以避免在哈希表调整大小时必须重新计算所有哈希码。

如果您知道某个键的哈希码将要更改,则需要在对该键进行突变之前将其从表中删除,然后再添加回去。(如果您在更改密钥后尝试

remove
/
put
,则很可能
remove
会找不到该条目。)

到底是怎么回事?

发生的情况是您违反了

HashMap
javadocs中明确规定的合同。不要那样做!



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/470199.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号