关于Object.hashcode()和碰撞

时间:2015-12-17 11:44:57

标签: java hashcode hash-collision

我正在阅读Object.hashCode hashCode方法,它说

  

尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数[...]

来实现

但无论它的实现是什么,Integer.MAX+1方法总是返回一个(让我们假设为正)整数,所以给定Integer.MAX+1个不同的对象,其中两个将具有相同的哈希码。

为什么JavaDoc在这里“否认”冲突?这是一个实际的结论,因为使用了内部地址并且“来了,你永远不会在内存中同时拥有2015-12-17 11:37:38.0845 | 64 | INFO | ----------------------------------- 2015-12-17 11:37:38.0845 | 64 | INFO | Statistics: 2015-12-17 11:37:38.0845 | 64 | INFO | Crawling Requests 46887 /min 2015-12-17 11:37:38.0845 | 64 | INFO | Stored Documents 9910 /min 2015-12-17 11:37:38.0845 | 64 | INFO | ----------------------------------- 个对象,所以我们可以说它几乎总是唯一的” ?

修改

JavaDoc(谢谢bug entry)给出了我的意思(这似乎是一个超过10年的讨论):

  

似乎许多(可能是大多数)程序员认为这意味着默认实现,因此System.identityHashCode将产生唯一的哈希码。

     

资格“尽可能合理地实际”,实际上不足以说明哈希码在实践中并非不同。

3 个答案:

答案 0 :(得分:3)

这些文档确实具有误导性,并且有一个bug在很久以前打开,说文档具有误导性,特别是实现是JVM依赖的,并且在实践中特别是对于大量堆大小它在将对象标识映射到32位整数时,很可能会发生冲突

答案 1 :(得分:0)

这里有一个关于哈希码冲突的有趣讨论:

http://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/

特别是,这突出了你的实际结论,“你永远不会在内存中同时拥有Integer.MAX + 1个对象,所以我们可以说它实际上总是独一无二的”距离准确很远birthday paradox

链接的结论是,假设hashCodes的随机分布,在我们有50/50的hashCode碰撞机会之前,我们只需要77,163个对象。

答案 2 :(得分:0)

当您仔细阅读本文时,您会注意到这只会意味着物品应该尽量避免碰撞(尽可能合理地实施'),但也不能保证您有不同之处不等对象的哈希码。

所以承诺不是很强,但它仍然非常有用。例如,在进行全面检查之前使用哈希码作为相等的快速指示。

例如ConcurrentHashMap将使用(在其上执行的函数)哈希码将位置分配给地图中的对象。在实践中,哈希码用于查找对象大致位于的位置,并且equals用于查找精确定位的对象。

如果对象不尽可能地尝试传播其哈希码,则哈希映射无法使用此优化。