Java 计算整数数组哈希值而不发生冲突的最快方法

Java 计算整数数组哈希值而不发生冲突的最快方法,java,arrays,integer,hashcode,Java,Arrays,Integer,Hashcode,Java方法Arrays.hashCode()或Objects.hash()为某些具有不同内容的整数数组返回相同的哈希值,例如 Integer[] a = {0,4,5,0} // hash 927520 Integer[] b = {0,3,36,0} // hash 927520 自定义hashcode方法返回相同的结果,例如: public int hash(final Integer[] indexes) { final int prime = 31; i

Java方法Arrays.hashCode()或Objects.hash()为某些具有不同内容的整数数组返回相同的哈希值,例如

Integer[] a = {0,4,5,0}     // hash 927520
Integer[] b = {0,3,36,0}    // hash 927520
自定义hashcode方法返回相同的结果,例如:

public int hash(final Integer[] indexes) {
    final int prime = 31;
    int result = 1;
    for (Integer i : indexes) {
        result = prime * result + ((i == null) ? 0 : i.hashCode());
    }
    return result;
}
我同意这是预期的行为。但是,由于内容不同,我想为它们生成不同的哈希代码


计算整数数组哈希而不发生冲突的最快方法是什么

无法满足您的要求

您必须了解散列函数可以而不是创建双向映射。这就是你在这里需要的

意思:有(接近)无限多个数组具有任意int值。如果每个散列都应该唯一地指向特定的数组设置,则可以通过其散列来标识每个数组。但是int(或long)的范围不是无限的。有比int值更多的数组组合来计算它们

不能将不确定集映射到非不确定集

换句话说:如果存在这样的散列方法,您可以将其转换为压缩算法,将任何内容减少为单个int值


所以:冲突是散列算法的固有属性。你无法回避它们。如果有的话,您可以微调特定的哈希函数,以最小化特定输入数据集的冲突。但正如所说:从概念/数学的角度来看,你所要求的是不可能的

问题有点不同。首先想一想为什么您需要以=开始使用
hashCode
,以便快速(er)查找。拥有两个将生成相同散列的对象根本不是问题,因为这当然并不意味着它们是相同的(您仍然会检查
等于

你已经在你的问题下发表了一些评论,说这是不可能的,我只是想补充一些你没有想到的有趣的事情(可能是你根本不知道)

一般来说,
散列冲突
在您可能想象的java数据结构中要频繁得多。根据并考虑到
散列
实际上是
32位
,我们得到这样一个事实,即只有77164个唯一值才会有
50%的机会产生冲突(这是最好的情况)。所以碰撞是非常好的。也就是说,需要改进这一点(在我的理解中,首先将hash-a
设置为long
,并将其处理掉;但没有深入研究它)


既然您知道散列冲突有那么好,那么想想为什么要使用它们。基本上用于快速(er)查找。当有两个条目具有相同的
hash
时,这意味着它们将以相同的“bucket”结尾,在java中,该bucket是一个完全平衡的红黑树(对于
HashMap
,因此,
HashSet
),在查找条目时仍然非常快速。因此,一般来说,任何基于哈希的结构都有一个恒定的搜索时间(即:摊销
O(1)
),因此不必担心哈希冲突

不可能。由于hashcode是整数,因此只有长度为1的整数数组才能具有无冲突的hashcode。一旦数组中有超过1个整数,该数组的可能值的数量就会大于可能的哈希代码的数量。无法保证具有不同内容的数组始终具有不同的哈希代码,因为可能的整数数组多于可能的哈希代码。请参阅:。没有办法100%避免碰撞。是什么让你认为你想要避免碰撞?散列冲突通常被认为是完全正常的。通过使用一个大于数组中预期数量的素数,您将能够避免相对较多(当然不是全部)的冲突。例如,如果您的数字增加到36左右,请选择127,例如.Related。说得好。让我添加:默认的
HashMap
HashSet
有16个bucket,并且在添加12个元素后仍然有16个bucket。在这一点上,即使使用一个完全分布的哈希函数,您至少有99.7%的概率发生一次冲突。@OleV.V。是的,这是因为HashMap内部的工作方式,在这些条件下,它只使用最后4位来选择bucket…另请参见@Maithilish@OleV.V. 别误会我的意思,但我写的答案在这个问题上更好:)对彼得表示了充分的尊重。这也是一篇非常古老的文章,事情已经改变了很多