使用哈希码获取唯一ID

我在基于java的系统中工作,我需要在可视化显示中为某些元素设置id。 一类元素是字符串,所以我决定使用String.hashCode()方法来获取这些元素的唯一标识符。

然而,我遇到的问题是,如果id为负数且String.hashCode经常返回负值,我在borks工作的系统。 一个快速的解决方案是在hashcode调用周围使用Math.abs()来保证正结果。 我对这种方法感到疑惑的是,两个不同元素具有相同哈希码的可能性是多少?

例如,如果一个字符串返回的哈希码为-10,而另一个字符串返回的哈希码为10,则会发生错误。 在我的系统中,我们讨论的是通常不超过30个元素的对象集合,所以我不认为这确实是一个问题,但我很好奇数学所说的。

哈希码可以被认为是伪随机数。 统计上,使用正的int哈希码,当群体大小约为54K( 任何 int为77K)时,任何两个元素之间发生冲突的可能性达到50%。 有关各种哈希码大小的冲突概率,请参阅生日问题概率表 。

另外,你单独使用Math.abs()想法是有缺陷的:它并不总是返回正数! 在2的恭维算术中, Integer.MIN_VALUE的绝对值本身就是! 众所周知, "polygenelubricants"的哈希码就是这个值。

哈希不是唯一的,因此它们不适合uniqueId

至于哈希冲突的概率,你可以阅读生日悖论 。 实际上(根据我的记忆)当从均匀分布的N值绘制时,你应该在绘制$ \ sqrt(N)$之后发生碰撞(你可以更早地得到碰撞)。 问题是Java的hashCode实现(特别是散列短字符串时)并不能提供统一的分布,所以你会更早地得到碰撞。

您已经可以获得具有相同哈希码的两个字符串。 如果您认为您拥有无限数量的字符串并且只有2 ^ 32个可能的哈希码,那么这应该是显而易见的。

在获取绝对值时,你只需要更有可能。 风险很小,但如果您需要一个唯一的ID,这不是正确的方法。

如果您只有30-50个值,那么您可以执行的操作是将每个字符串与运行计数器一起注册到HashMap中作为值:

 HashMap StringMap = new HashMap(); StringMap.add("Test",1); StringMap.add("AnotherTest",2); 

然后,您可以通过调用以下方式获取您的唯一ID:

 StringMap.get("Test"); //returns 1