Java方法,Arrays.hashCode()或Objects.hash()为具有不同内容的某些Integer数组返回相同的哈希值,例如
Integer[] a = {0,4,5,0} // hash 927520
Integer[] b = {0,3,36,0} // hash 927520
自定义哈希码方法返回相同的结果,例如:
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;
}
我同意这是预期的行为。但是,我想为它们生成不同的哈希码,因为内容不同。
在没有碰撞的情况下计算整数数组的散列的最快方法是什么
问题有点不同。首先想一想为什么你需要hashCode
开始=快速(呃)查找。有两个生成相同哈希的对象根本不是问题,因为这并不意味着它们是相同的,当然(你仍然会检查equals
)。
你已经在你的问题上做了一些评论,说这是不可能的,我只是想添加一些你没想过的有趣的东西(可能你根本就不知道它们)。
通常,hash collisions
在您可能想象的Java数据结构中更频繁。根据Birthday problem并考虑到hash
实际上是32 bits
,我们得出这样的事实:在50%
产生碰撞之前它只需要77,164个唯一值(这是最好的情况)。所以碰撞不仅仅是好事。话虽这么说,有JEP来改善这一点(在我的理解中,首先制作哈希 - 一个long
并解决这个问题;但是并没有深入研究它)。
现在您已经知道哈希冲突更加精细,请考虑使用它们的原因。基本上用于快速(呃)查找。当有两个条目具有相同的hash
时,这意味着它们将以相同的“桶”结尾,而在java中,该桶是一个完美平衡的红黑树(对于HashMap
,因此,HashSet
) - 这仍然是超级的在寻找条目时快速。因此,通常,任何基于散列的结构都具有恒定的搜索时间(即:分摊的O(1)
),所以不要担心散列冲突。
没有办法满足您的要求。
您必须了解散列函数无法创建双向映射。这就是你需要的!
含义:有一个(接近)无限数量的具有任意int值的数组。如果每个哈希值应唯一地指向特定的数组设置,则可以通过其哈希标识每个数组。但int(或long)的范围并不是无限期的。有更多可能的数组组合而不是int值来计算它们!
您无法将不定的集映射到不确定的集合上。
换句话说:如果存在这样的散列方法,您可以将其转换为压缩算法,将任何内容减少为单个int值。
因此:冲突是哈希算法的固有属性。你无法避免它们。如果有的话,您可以微调特定的散列函数,以最大限度地减少特定输入数据集的冲突。但正如所说:从概念/数学的角度来看,你所要求的是不可能的。