我知道这似乎已经讨论过了,答案是肯定的, 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,我想用它为字符串生成一个唯一的主键。看来我做得不对。有什么建议吗?
非常感谢!
5条答案
按热度按时间g9icjywg1#
在这种情况下,我确实需要hashcode,我想用它为字符串生成一个唯一的主键。看来我做得不对。有什么建议吗?
在使用散列值主键时应始终保持谨慎。它们不是唯一的。哈希函数的取值范围越小,问题就越严重。
就你而言,
hashcode
(以及identityHashcode()
方法)生成一个32位的值。对于任意一对随机生成的两个不同字符串,哈希码有1/2^32是相同的。这适用于任何生成(32位)哈希代码的方法。现在(大约)20亿分之一的可能性听起来并不多。但你不需要仅仅是成对的唯一性。实际上,您需要所有字符串的哈希码都是唯一的。。。因为您试图将哈希代码用作主键,并且主键必须是唯一的。维基百科页面“生日问题”上的表格说,在碰撞概率上升到1/4之前,你只需要大约50000个键(对。。。四分之一!)
总之,不要使用
hashcode()
值作为主键。同一个表表示生成128位哈希值的好哈希函数可能足以避免冲突。但是你要自己检验一下可能性,做出自己的判断。
xoefb8l82#
你误解了
.hashCode()
.合同的一部分是
equals()
必须有相同的hashCode()
. 然而,事实并非如此:两个具有相同属性的对象hashCode()
不必是equals()
.这是一个有效的,尽管毫无用处,
hashCode()
实施:您应该使用字符串本身作为“主键”。如果您想要一个“更有效”的键,您应该考虑输入字符串的格式,如果可能的话,提取这个输入的重要部分。
a0zr77ik3#
明智的选择是使用字符串作为主键(另一种选择是将guid与数据记录相关联,并将其作为主键。)
散列意味着(1)快速和(2)使得两个相等的字符串具有相同的散列码。
我认为你很可能会遇到散列冲突;毕竟一个
int
(散列返回类型)只有大约40亿个不同的值。aoyhnmkz4#
你可以用
以获得独特的结果。
编辑
我认为guava的杂音哈希实现可能也有帮助:
一般来说,杂音散列应该是快速和可靠的。
vzgqcmou5#
可以使用sha1哈希算法来降低冲突概率。请看以下代码片段,了解如何在java中计算sha1哈希:http://www.sha1-online.com/sha1-java/