如何使用string.hashcode生成主键

evrscar2  于 2021-07-09  发布在  Java
关注(0)|答案(5)|浏览(269)

我知道这似乎已经讨论过了,答案是肯定的, String.hashCode 可以为不同的字符串生成相等的值,但不太可能(java的哈希代码可以为不同的字符串生成相同的值吗?)。然而,它确实发生在我的应用程序。
以下代码将生成相同的哈希代码:-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,我想用它为字符串生成一个唯一的主键。看来我做得不对。有什么建议吗?
非常感谢!

g9icjywg

g9icjywg1#

在这种情况下,我确实需要hashcode,我想用它为字符串生成一个唯一的主键。看来我做得不对。有什么建议吗?
在使用散列值主键时应始终保持谨慎。它们不是唯一的。哈希函数的取值范围越小,问题就越严重。
就你而言, hashcode (以及 identityHashcode() 方法)生成一个32位的值。对于任意一对随机生成的两个不同字符串,哈希码有1/2^32是相同的。这适用于任何生成(32位)哈希代码的方法。
现在(大约)20亿分之一的可能性听起来并不多。但你不需要仅仅是成对的唯一性。实际上,您需要所有字符串的哈希码都是唯一的。。。因为您试图将哈希代码用作主键,并且主键必须是唯一的。维基百科页面“生日问题”上的表格说,在碰撞概率上升到1/4之前,你只需要大约50000个键(对。。。四分之一!)
总之,不要使用 hashcode() 值作为主键。
同一个表表示生成128位哈希值的好哈希函数可能足以避免冲突。但是你要自己检验一下可能性,做出自己的判断。

xoefb8l8

xoefb8l82#

你误解了 .hashCode() .
合同的一部分是 equals() 必须有相同的 hashCode() . 然而,事实并非如此:两个具有相同属性的对象 hashCode() 不必是 equals() .
这是一个有效的,尽管毫无用处, hashCode() 实施:

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

您应该使用字符串本身作为“主键”。如果您想要一个“更有效”的键,您应该考虑输入字符串的格式,如果可能的话,提取这个输入的重要部分。

a0zr77ik

a0zr77ik3#

明智的选择是使用字符串作为主键(另一种选择是将guid与数据记录相关联,并将其作为主键。)
散列意味着(1)快速和(2)使得两个相等的字符串具有相同的散列码。
我认为你很可能会遇到散列冲突;毕竟一个 int (散列返回类型)只有大约40亿个不同的值。

aoyhnmkz

aoyhnmkz4#

你可以用

System.identityHashcode(Object);

以获得独特的结果。
编辑
我认为guava的杂音哈希实现可能也有帮助:

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

一般来说,杂音散列应该是快速和可靠的。

vzgqcmou

vzgqcmou5#

可以使用sha1哈希算法来降低冲突概率。请看以下代码片段,了解如何在java中计算sha1哈希:http://www.sha1-online.com/sha1-java/

相关问题