我有一些长度很短的字符串(少于10个字符)。我会将它们转换成整数并用作主键。 (由于小问题,我不能使用字符串主键。)我知道无限长度的字符串哈希码可能会冲突,但是短字符串也会发生冲突吗?
我有一些长度很短的字符串(少于10个字符)。我会将它们转换成整数并用作主键。 (由于小问题,我不能使用字符串主键。)我知道无限长度的字符串哈希码可能会冲突,但是短字符串也会发生冲突吗?
当然可以。例如,Ea
和 FB
是碰撞字符串,每个字符串只有两个字符的长度!示例:
public static final void main(String[] args) {
System.out.println("Ea".hashCode() + " " + "FB".hashCode());
}
打印出 2236 2236
。
Java中的String#hashCode
函数并不像随机函数一样随机。对于短字符串来说,很容易生成哈希冲突;即使是对于长字符串而言,其表现也没有明显改善。
一般情况下,即使你只使用每个字符6位(ASCII字母和数字以及一些符号),当你使用一个6个字符的字符串时就已经超过了32位哈希码的可能值 -- 也就是说,在2^36个6位字符的字符串中将绝对保证会有哈希冲突。
哈希码的大小为32位。
在Java中,char
大小为16位。
因此,在理论上,所有2个字符的字符串都可以具有不同的哈希码,尽管其中一些哈希码必须与空字符串和单字符字符串的哈希码发生冲突。即使只考虑“所有两个字符或更短的字符串”,也会发生冲突。到你有10个字符时,可能性会更多,超过了可用的哈希码数量。
冲突仍然很少见,但您应该始终假设它们可能发生。