最快的方法来计算没有碰撞的整数数组的哈希值

问题描述 投票:4回答:2

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;
}

我同意这是预期的行为。但是,我想为它们生成不同的哈希码,因为内容不同。

在没有碰撞的情况下计算整数数组的散列的最快方法是什么

java arrays integer hashcode
2个回答
2
投票

问题有点不同。首先想一想为什么你需要hashCode开始=快速(呃)查找。有两个生成相同哈希的对象根本不是问题,因为这并不意味着它们是相同的,当然(你仍然会检查equals)。

你已经在你的问题上做了一些评论,说这是不可能的,我只是想添加一些你没想过的有趣的东西(可能你根本就不知道它们)。

通常,hash collisions在您可能想象的Java数据结构中更频繁。根据Birthday problem并考虑到hash实际上是32 bits,我们得出这样的事实:在50%产生碰撞之前它只需要77,164个唯一值(这是最好的情况)。所以碰撞不仅仅是好事。话虽这么说,有JEP来改善这一点(在我的理解中,首先制作哈希 - 一个long并解决这个问题;但是并没有深入研究它)。

现在您已经知道哈希冲突更加精细,请考虑使用它们的原因。基本上用于快速(呃)查找。当有两个条目具有相同的hash时,这意味着它们将以相同的“桶”结尾,而在java中,该桶是一个完美平衡的红黑树(对于HashMap,因此,HashSet) - 这仍然是超级的在寻找条目时快速。因此,通常,任何基于散列的结构都具有恒定的搜索时间(即:分摊的O(1)),所以不要担心散列冲突。


1
投票

没有办法满足您的要求。

您必须了解散列函数无法创建双向映射。这就是你需要的!

含义:有一个(接近)无限数量的具有任意int值的数组。如果每个哈希值应唯一地指向特定的数组设置,则可以通过其哈希标识每个数组。但int(或long)的范围并不是无限期的。有更多可能的数组组合而不是int值来计算它们!

您无法将不定的集映射到不确定的集合上。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.