对象哈希码更改时,在Hashmap或Hashset中查找会发生什么情况 [英] What happens to the lookup in a Hashmap or Hashset when the objects Hashcode changes

查看:162
本文介绍了对象哈希码更改时,在Hashmap或Hashset中查找会发生什么情况的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Hashmap中,提供的键的哈希码用于将值放入散列表中。在Hashset中,obects哈希码用于将值放置在底层哈希表中。即hashmap的优点是你可以灵活地决定你想要什么作为关键,这样你就可以做出像这样的好事情。

 地图<字符串,玩家GT; players = new HashMap< String,Player>(); 

这可以将玩家名称等字符串映射到玩家本身。



我的问题是当密钥的哈希码更改时,查找会发生什么。

这个我认为对于一个HashMap来说不是一个主要的问题,因为我不希望也不想改变这个关键。在前面的例子中,如果球员名字改变,他不再是那个球员。不过,我可以使用键更改其他字段,而不是名称和未来查找将起作用。



然而,在Hashset中,整个对象的哈希码是用于放置该项目,如果有人稍微改变了一个对象,将来对该对象的查找将不再解析到Hashtable中的相同位置,因为它依赖于整个对象Hashcode。这是否意味着一旦数据在Hashset中就不应该改变。还是需要重新设计?或者它是自动完成的?这是怎么回事?在你的例子中,一个String是不可变的,所以它的hashcode不能改变。但假设,如果一个对象的散列码确实发生了变化,而且是散列表中的一个关键字,那么就散列表查找而言,它可能会消失。我在这里回答了更多相关问题的相关问题: https://stackoverflow.com/a/13114376/139985 。 (原始问题是关于 HashSet ,但是 HashSet 确实是 HashMap ,所以答案也覆盖了这个例子。)



可以肯定地说,如果HashMap或者TreeMap的键都是以一种影响它们各自的 hashcode() / equals(Object) compare (...) compareTo(...)合约,那么数据结构将断开。







这是否意味着一旦数据处于Hashset中,就不应该改变它。


是的。


还是需要重新编制?或者它是自动完成的?


它不会自动重新排序。 HashMap 不会注意到密钥的哈希码已经改变。实际上,当 HashMap 调整大小时,甚至不会重新获得哈希码。数据结构会记住原始哈希码值,以避免在哈希表调整大小时重新计算所有哈希码。



如果您知道密钥的哈希码将改变,您需要从表中删除条目,然后再修改密钥,然后将其添加回去。 (如果您在变更密钥后尝试删除 / 放置,则可能是删除将无法找到该条目。)


发生了什么事?


发生的事情是您违反了 HashMap javadocs中清楚列出的合同。别这样做!


In a Hashmap the hash code of the key provided is used to place the value in the hashtable. In a Hashset the obects hashcode is used to place the value in the underlying hashtable. i.e the advantage of the hashmap is that you have the flexibility of deciding what you want as the key so you can do nice things like this.

Map<String,Player> players = new HashMap<String,Player>();

This can map a string such as the players name to a player itself.

My question is is what happens to to the lookup when the key's Hashcode changes.

This i expect isn't such a major concern for a Hashmap as I wouldn't expect nor want the key to change. In the previous example if the players name changes he is no longer that player. However I can look a player up using the key change other fields that aren't the name and future lookups will work.

However in a Hashset since the entire object's hashcode is used to place the item if someone slightly changes an object future lookups of that object will no longer resolve to the same position in the Hashtable since it relies on the entire objects Hashcode. Does this mean that once data is in a Hashset it shouldnt be changed. Or does it need to be rehashed? or is it done automatically etc? What is going on?

解决方案

In your example, a String is immutable so its hashcode cannot change. But hypothetically, if the hashcode of an object did change while was a key in a hash table, then it would probably disappear as far as hashtable lookups were concerned. I went into more detail in this Answer to a related question: https://stackoverflow.com/a/13114376/139985 . (The original question is about a HashSet, but a HashSet is really a HashMap under the covers, so the answer covers this case too.)

It is safe to say that if the keys of either a HashMap or a TreeMap are mutated in a way that affects their respective hashcode() / equals(Object) or compare(...) or compareTo(...) contracts, then the data structure will "break".


Does this mean that once data is in a Hashset it shouldnt be changed.

Yes.

Or does it need to be rehashed? or is it done automatically etc?

It won't be automatically rehashed. The HashMap won't notice that the hashcode of a key has changed. Indeed, you won't even get recomputation of the hashcode when the HashMap resizes. The data structure remembers the original hashcode value to avoid having to recalculate all of the hashcodes when the hash table resizes.

If you know that the hashcode of a key is going to change you need to remove the entry from the table BEFORE you mutate the key, and add it back afterwards. (If you try to remove / put it after mutating the key, the chances are that the remove will fail to find the entry.)

What is going on?

What is going on is that you violated the contract set out clearly in the HashMap javadocs. Don't do that!

这篇关于对象哈希码更改时,在Hashmap或Hashset中查找会发生什么情况的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆