java – 当对象Hashcode更改时,在Hashmap或Hashset中查找会发生什么

在Hashmap中,提供的密钥的哈希码用于将值放在哈希表中.在Hashset中,使用哈希码来将值放在底层哈希表中.即,hashmap的优点在于,您可以灵活地决定所需的内容作为关键,以便您可以做到这样的美好事物.
Map<String,Player> players = new HashMap<String,Player>();

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

我的问题是当密钥的Hashcode更改时,查找会发生什么.

这个我期望的不是哈希图的一个主要的问题,因为我不会指望,也不希望改变关键.在前面的例子中,如果玩家名字改变,他不再是那个玩家.然而,我可以使用关键更改的其他字段来查找一个播放器,而不是名称和将来的查找将会起作用.

然而,在Hashset中,由于整个对象的哈希码用于放置项目,如果有人稍微更改对象,则该对象的未来查找将不再解析为Hashtable中的相同位置,因为它依赖于整个对象Hashcode.这是否意味着一旦数据在Hashset中,就不应该改变.还是需要重新打?还是自动完成?到底是怎么回事?

解决方法

在你的例子中,一个String是不可变的,所以它的hashcode不能改变.但是假设,如果一个对象的哈希码确实改变了,而哈希表中的一个键,那么就可能会消失,就哈希表查找而言.我在这个答案中详细介绍了一个相关的问题: https://stackoverflow.com/a/13114376/139985. (原来的问题是关于一个HashSet,但一个HashSet真的是一个HashMap的封面,所以答案也涵盖了这个例子.)

可以肯定的是,如果HashMap或TreeMap的密钥以影响其各自的hashcode()/ equals(Object)或compare(…)或compareTo(…)合同的方式进行突变,则数据结构将“打破”.

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?

它不会被自动重新打开. HashMap不会注意到键的哈希码已经改变了.实际上,当HashMap调整大小时,你甚至不会重新计算hashcode.数据结构记住原始的哈希码值,以避免在散列表调整大小时重新计算所有的哈希码.

如果您知道密钥的哈希码将要更改,则在更改密钥之前,您需要从表中删除该条目,然后将其重新添加. (如果您尝试在突变密钥后删除/放置,则删除将无法找到该条目.)

What is going on?

发生的是您违反了HashMap javadocs中明确规定的合同.不要这样做

相关文章

ArrayList简介:ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增...
一、进程与线程 进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。 线程...
本文为博客园作者所写:&#160;一寸HUI,个人博客地址:https://www.cnblogs.com/zsql/ 简单的一个类...
#############java面向对象详解#############1、面向对象基本概念2、类与对象3、类和对象的定义格式4、...
一、什么是异常? 异常就是有异于常态,和正常情况不一样,有错误出错。在java中,阻止当前方法或作用域...
Collection接口 Collection接口 Collection接口 Collection是最基本的集合接口,一个Collection代表一组...