为什么值类的值作为其hashCode"不是一个好主意"?

时间:2014-11-08 20:05:04

标签: java hash hashmap hashcode

有效Java,第二个Edn,J。Bloch 第9项的最后一段 对于IntegerStringDate等价值类别说, 返回该类的确切值的函数 hashCode不是一个好主意

因此,类Integer返回它所代表的整数value作为其实例的hashCode并不是那么好。

String的{​​{3}}都没有返回从整体内容直接映射的整数值,即String实例所具有的字符。

这些hashCode() - s明显符合合同。

对我来说,它似乎是一个好主意而不是一个坏主意 - hashCode - s随着对象的值不同而变化,这些hashCodes是"标准化&# 34;在它们分散到HashMap / HashSet的桶中之前 - 这些条目的hashCode - s不会形成对条目将进入哪个桶的偏差。

我在这里缺少什么 - 是什么让类值直接映射到hashCode a"坏主意"?

TIA

// ===========================

修改

请参阅史蒂夫·西伯特关于此的回答。

3 个答案:

答案 0 :(得分:4)

它说的是那些javadoc规范确切地说明了hashCode是如何创建的。通过这样做,应用程序现在可以始终依赖于此...现在这些实现永远不会改变生成hashCode的方式。

这并不意味着你不应该从你的价值中得出你的哈希...只是不要告诉别人你在规范中如何做到这一点=)

答案 1 :(得分:3)

full quote

  

Java平台库中的许多类,例如String,   IntegerDate在其规范中包含确切的值   由hashCode方法返回,作为实例值的函数。   这通常不是一个好主意,因为它严重限制了你的能力   在将来的版本中改进哈希函数。如果你离开了   未指定散列函数的细节,发现缺陷或更好   发现哈希函数,你可以改变一个哈希函数   随后的发布,确信没有客户依赖于确切的   哈希函数返回的值。

强调我的。本书只是说明在规范中揭示实现细节通常被认为是不好的做法。这使它无法改变。

它被实现为返回精确值(对于Integer)或某个计算值(对于DateString)这一事实并不错。

答案 2 :(得分:-1)

Java API就是这样,它返回整数。

Integer t = ...;
t.intValue() == t.hashCode(); // true

我在工作中有同一本书。我会在周一看一下。

如果您真的很担心,请实施FNV-1a哈希:

    int hash = 0x4C1DF00D;
    hash = (hash ^ value) * 0x01000193;