不,您不需要有一个返回唯一值的实现,“显然”,因为显然大多数实现都会被破坏。
你想做的是,在位之间有一个很好的分布,特别是对于共同的值(如果任何值比其他值更常见)。除非对您的格式有特殊的了解,否则最好只使用字符串本身的哈希码。
通过对id格式限制的特殊了解,可以进行自定义并产生更好的性能,尽管错误的假设更有可能使事情变得更糟而不是更好。
编辑:关于位的良好传播。
正如这里和其他答案中所述,完全唯一是不可能的,并且哈希冲突是可能的。使用哈希的方法知道这一点并且可以处理它,但它确实会影响性能,因此我们希望冲突很少见。
此外,哈希通常被重新散列,因此我们的32位数字最终可能会被减少到例如0到22范围内的一个,我们希望尽可能好地分布在其中。
我们还希望平衡这一点,不要花费太长时间来计算我们的哈希值,以至于它本身就成为瓶颈。一种不完美的平衡行为。
错误哈希方法的一个经典示例是 X,Y 整数的坐标对,它具有以下功能:
return X ^ Y;
虽然这在从4 ^ 32个可能的输入中返回2 ^ 32个可能的值方面做得很好,但在现实世界中使用中,具有X和Y相等的坐标集({0,0},{1,1},{2,2}等)是很常见的,这些坐标集都散列为零,或者匹配对({2,3}和{3, 2}) 将散列到相同的数字。我们可能通过以下方式获得更好的服务:
return ((X << 16) | (x >> 16)) ^ Y;
现在,有许多可能的值比前者可怕,但它往往在现实世界中服务更好。
当然,如果你正在编写一个通用类(不知道有什么可能的输入)或者对手头的目的有更好的了解,那就有不同的工作了。例如,如果我使用Date对象,但知道它们都只是日期(时间部分总是午夜),并且仅在彼此相距几年内,那么我可能更喜欢仅使用年份的日,月和较低数字的自定义哈希代码,而不是标准哈希代码。虽然的作者不能研究这些知识,但必须努力满足每个人的需求。Date
因此,例如,如果我知道一个给定的字符串总是由[a-z]或[0-9]范围内的6个不区分大小写的字符组成(你的似乎是这样,但从你的问题中看不出它是否确实如此),那么我可能会使用一种算法,为每个字符分配一个从0到35的值(每个字符的36个可能值), 然后遍历字符串,每次将当前值乘以 36 并加上下一个字符的值。
假设ids的良好传播,这将是要走的路,特别是如果我的顺序使得我的哈希中较低的有效数字与id中变化最频繁的char相匹配(如果可以进行这样的调用),因此可以很好地重新散列到较小的范围。
但是,由于缺乏对格式的了解,我无法确定地进行该调用,并且我很可能使事情变得更糟(算法较慢,哈希质量几乎没有甚至负增益)。
您拥有的一个优点是,由于它本身就是一个ID,因此可能没有其他不相等的对象具有相同的ID,因此不需要检查其他属性。这并不总是成立的。