如何使用String.hashCode生成主密钥



我知道这似乎已经讨论过,答案是肯定的, String.hashCode可以为不同的字符串生成相等的阀门,但不太可能(Java的Hashcode可以为不同的字符串产生相同的值吗?)。但是它确实发生在我的应用程序中。

以下代码将产生相同的哈希码:-347019262(Jave 1.7.25)

String string1 = "/m/06qw_";
String string2="/m/0859_";
System.out.println(string1+","+string1.hashCode());
System.out.println(string2+","+string2.hashCode());

在这种情况下,我确实需要哈希码,我想使用它来为字符串生成唯一的主键。看来我做得不对。请提出任何建议吗?

非常感谢!

你误解了 .hashCode()

合同的一部分是equals()的对象必须具有相同的hashCode()。但是,相反的不正确:两个具有相同hashCode() do 不是的对象必须是equals()

这是一个有效的,尽管是无用的,但hashCode()实现:

@Override
public int hashCode()
{
    return 42; // universal answer
}

您应该将字符串本身用作"主键"。如果您想要"更有效"的密钥,则应考虑输入字符串是什么格式,如果可能的话,请提取此输入的重要部分。

明智的选项是将字符串用作主键。(另一个选择是将GUID与您的数据记录相关联,并将其作为主要密钥。)

哈希是(1)快速和(2),以使两个平等的字符串具有相同的哈希代码。

我会提交可能的,您将获得哈希冲突;毕竟int(哈希返回类型)只有大约40亿个不同的值。

在这种情况下,我确实需要哈希码,我想使用它来为字符串生成唯一的主键。看来我做得不对。请提出任何建议吗?

您应该始终谨慎使用哈希值主键。它们不是唯一的。哈希函数的范围越小,问题越好。

在您的情况下,hashcode(评论中建议的identityHashcode()方法)生成32位值。对于任何两个不同的随机生成的字符串的任何对,有可能有1对2^32,即哈希尺相同。对于生成(32位)哈希代码的任何的方法都是如此。

现在,(大约)有1个中有1个中有1个的机会听起来不多。但是您不需要一对唯一性。实际上,您需要所有字符串的hashcodes的所有是唯一的……因为您正在尝试将其用作主要键,而主键必须是唯一的。Wikipedia页面上的表"生日问题"说,在碰撞的可能性上升到1英寸之前,您只需要50,000个钥匙。(是的...四分之一!)

简而言之,请勿将hashcode()值用作主要密钥。

同一表,指示A 良好的哈希函数,生成128位哈希值可能足以避免碰撞。但是请自己检查概率并做出自己的判断。

您可以使用SHA1哈希算法来降低碰撞概率。看看此片段以查看,如何计算Java中的SHA1 HASH:http://www.sha1-online.com/sha1-java/

您可以使用

System.identityHashcode(Object);

获得独特的结果。

编辑

我认为这可能是Hash Guava的实施也可以在这里提供帮助:

 HashFunction hash = Hashing.murmur3_128();
 hash.hashString("/m/06qw_", Charset.defaultCharset()).asInt();

通常应该快速可靠。

最新更新