Java hashCode()值在执行之间更改

Java hashCode()值在执行之间更改,java,serialization,hashcode,Java,Serialization,Hashcode,在应用程序的一次执行过程中,对象的hashCode必须与该对象保持一致-- 对于任何对象o,o.hashCode()应返回相同的int值 但是,这不一定是从一个运行时到另一个运行时:o.hashCode() 可以返回一些其他值,这是完全正确的 HashMap根据hashCode值计算右屈曲 我的问题是:这个值在一个会话到另一个会话之间的变化是如何处理的? 序列化是否具有处理此问题的功能 因此,假设我构建了一个散列并将其存储在磁盘上。两周后,我调用了应用程序 运行它。我正在散列中查找一个对象。通过

在应用程序的一次执行过程中,对象的hashCode必须与该对象保持一致-- 对于任何对象o,o.hashCode()应返回相同的int

但是,这不一定是从一个运行时到另一个运行时:o.hashCode() 可以返回一些其他值,这是完全正确的

HashMap根据hashCode值计算右屈曲

我的问题是:这个值在一个会话到另一个会话之间的变化是如何处理的? 序列化是否具有处理此问题的功能

因此,假设我构建了一个散列并将其存储在磁盘上。两周后,我调用了应用程序 运行它。我正在散列中查找一个对象。通过这些,的hashCode 此对象现在/可能与以前不同
虽然它在散列中,但我无法找到它

Object.hashCode()的一般约定,正如您所说,指定了哈希代码可以在运行之间更改

但是,如果您需要一个在两次运行之间不会更改的哈希代码,那么您只需使用自己的实现覆盖
hashCode()
,即可保证这一点

您的应用程序需求会施加额外的规则,但这些规则不会破坏常规的
Object.hashCode()
契约。因此,您可以安全地实现自己的
hashCode()
,满足您的需求,而不会有破坏其他任何功能的风险。请注意,
hashCode()
不要求在不同的运行中使用不同的哈希代码,它只允许这样做

顺便说一句,规范允许这样做的原因是,基本实现只返回对象的内存地址,这在运行之间可能有所不同。这有时适用于快速、一次性使用,但通常不适用。您通常希望实现一个基于业务值计算哈希代码的
hashCode()
,该哈希代码在运行之间是一致的,并且对于业务级别相等的对象(即具有相同值的两个
Integer
实例)也是相同的


正如Robin Green所指出的,Java的
HashMap
实现了自定义序列化,该序列化独立于存储时对象的哈希值。但是,如果您要实现自己的哈希表,并且只存储对象的哈希值,则无法保证在反序列化哈希表后可以找到对象(当然,除非您仅在其中存储具有一致的
hashCode()

这是因为哈希表没有序列化为哈希表。它们以自定义方式序列化。因此,反序列化时,将使用新的哈希代码重建哈希表。

序列化哈希表时,是序列化值,而不是哈希代码。序列化哈希代码是一个坏主意。

是否有一种方法可以按原样存储哈希映射及其整个结构?@Roam为什么要这样做?您已经知道不这样做的一个原因-运行之间哈希代码的可变性。此外,哈希表的组织是为了快速搜索,而不是节省空间。@Roam:你不需要问这个问题。从您的角度来看,您只关心
HashMap
是否已恢复。请注意,如果序列化的
HashMap
中的所有元素都使用基本的
Object.hashCode()
实现(通常返回对象实例的内存地址),那么在哈希映射中查找这些对象之前,您仍然必须以其他方式(
values()
)获取哈希映射中的对象列表,因为新实例化的对象永远不能与映射中的对象具有相同的哈希代码。这就是为什么您通常应该基于业务价值实现自己的
hashCode()
。@PatriciaShanahan想知道我能/不能用它做什么。但是我想把它保存在磁盘上并没有什么意义;它们是经过计算的,不需要存储。实际上,它们不能被哈希表缓存,因为这会导致无限回归的问题——哈希表需要另一个哈希表来查找其中的哈希代码。