Java 为异构密钥编写hashCode方法

Java 为异构密钥编写hashCode方法,java,performance,hashcode,Java,Performance,Hashcode,我有一个Java HashMap,它的键是Java.lang.Object的实例,也就是说:键是不同类型的。当两个不同类型的键对象包含相同的变量值时,它们的hashCode值可能相同 为了提高HashMap的get方法的性能,我倾向于将Java类型的名称混合到关键对象的hashCode方法中。我还没有在其他地方看到这样的例子,所以我的这个可能是古怪的警报响了。您认为将类型混合到哈希代码中是个好主意吗?我应该混入类名还是相关类对象的hashCode?我不会混入类型名-但是如果您已经控制了hashC

我有一个Java HashMap,它的键是Java.lang.Object的实例,也就是说:键是不同类型的。当两个不同类型的键对象包含相同的变量值时,它们的hashCode值可能相同


为了提高HashMap的get方法的性能,我倾向于将Java类型的名称混合到关键对象的hashCode方法中。我还没有在其他地方看到这样的例子,所以我的这个可能是古怪的警报响了。您认为将类型混合到哈希代码中是个好主意吗?我应该混入类名还是相关类对象的hashCode?

我不会混入类型名-但是如果您已经控制了
hashCode
算法,为什么不更改它以避免冲突呢?例如,如果您使用的是常见的“加法和乘法”方法,那么您可以从不同的基本情况开始,或者使用不同的乘法器


在你过分担心这个问题之前,你有没有测量过你与真实数据发生碰撞的频率?这肯定是一个问题,还是你只是担心这可能是一个问题?

我认为当你决定使用不同类型的钥匙时,你的这可能是一个奇怪的警报应该已经响起。但让我们假设在这种情况下,对象才是真正的方向

如果您发现这个特定的查找被确定为系统中的热点,那么您应该在不混合类型名称的情况下进行尝试,并对性能进行压力测试。很可能表现并不重要

与Jon暗示的一样,通过减少冲突来提高哈希映射的性能。在类型名称中混合使用会增加冲突,就像减少冲突一样。为了保持hashmap处于峰值状态,您希望任何特定hashcode的可能性与有效键值域上的任何其他hashcode的可能性大致相同。因此,哈希码为10的概率应该与100或任何其他数字的概率大致相同。这样一来,散列表存储桶(很可能)会均匀填充。因此,您是否拥有类型A或类型B的对象并不重要。只是所有出现键值的哈希码的概率分布。

年后

除了这是一个过早的优化之外,这不是一个坏主意,开销也很小。Choy建议首先进行概要分析,这在总体上肯定是好的,但有时一个简单的优化比概要分析花费的时间要少得多。这似乎是这样的情况

我会使用一个已经建议过的不同的乘数,并混合使用
getClass().getHashCode()


或者可能是
getClass().getName().getHashCode()
,因为它在JVM调用中保持一致,如果您想要一个可复制的
HashMap
迭代顺序以便于调试,这可能会有所帮助。请注意,您永远不应该依赖于这样的可再现性,而且有很多东西会破坏它。

过早优化是有害的。好的想法,Jon。我知道会有碰撞;但我不知道这些冲突会对用户可检测性能产生什么影响。所以…公正的评论;也许我应该把它当作一个问题放在一边,直到它跳起来大叫“修理我!”。