Bic*_*ick 14 java casting unique
我有一个带有String的对象,该String包含唯一的id.(例如"ocx7gf"或"67hfs8")我需要为它提供一个int hascode()的实现,这显然是唯一的.
如何以最简单/最快的方式将字符串转换为唯一的int?
10X.
编辑 - 好的.我已经知道String.hashcode是可能的.但不建议在任何地方使用.实际上'如果不推荐任何其他方法 - 我是否应该使用它,如果我的对象在集合中,我需要哈希码.我应该将其连接到另一个字符串以使其更成功吗?
Jon*_*nna 21
不,你没有需要有一个返回独特价值的实现,"很明显",因为很明显多数的实现将被打破.
你想要做的是在比特上有一个很好的分布,特别是对于普通值(如果任何值比其他值更常见).除非您对格式有特殊了解,否则只需使用字符串本身的哈希码即可.
凭借对id格式限制的特殊了解,可以自定义并获得更好的性能,但错误的假设更可能使事情变得更糟.
编辑:在比特的良好传播.
如此处和其他答案中所述,完全唯一是不可能的,并且哈希冲突是可能的.哈希使用方法知道这个并且可以处理它,但它确实会影响性能,所以我们希望碰撞很少见.
此外,散列通常被重新散列,因此我们的32位数可能最终减少到例如0到22之间的一个,并且我们希望尽可能好地分配.
我们还希望平衡这一点,而不是花费很长时间来计算我们的哈希值,它本身就成了一个瓶颈.不完美的平衡行为.
坏哈希方法的一个典型示例是一对X,Y整数的坐标,其中:
return X ^ Y;
Run Code Online (Sandbox Code Playgroud)
虽然这样可以很好地从4 ^ 32个可能的输入中返回2 ^ 32个可能的值,但在实际使用中,使用X和Y相等的坐标集是很常见的({0,0},{1所有散列为零的匹配,或匹配对({2,3}和{3,2})将散列到相同的数字,1},{2,2}等等.我们可能更好地服务于:
return ((X << 16) | (x >> 16)) ^ Y;
Run Code Online (Sandbox Code Playgroud)
现在,是同样多的可能值,也是它比前可怕的,但它往往服务于现实世界的情况下更好.
当然,如果你正在编写一个通用课程(不知道有什么可能的输入)或者更好地了解手头的目的,那么就会有不同的工作.例如,如果我使用Date对象但知道它们都只是日期(时间部分总是午夜)并且只在几年之内,那么我可能更喜欢仅使用日,月和年份的低位数,超过标准的数字.Date
虽然作者不能在这些知识上工作,但必须尽力满足每个人的需求.
因此,如果我知道一个给定的字符串总是由[az]或[0-9]范围内的6个不区分大小写的字符组成(你似乎是这样,但是你的问题并不清楚然后我可能会使用一个算法,为每个字符分配一个0到35之间的值(每个字符的36个可能的值),然后遍历字符串,每次将当前值乘以36并添加值下一个字符.
假设在ID中有一个很好的传播,这将是要走的路,特别是如果我做了这样的命令,使得我的哈希值中的较低有效数字与id中最频繁更改的字符匹配(如果可以进行这样的调用)因此可以很好地重新散列到较小范围内.
然而,由于缺乏对格式的这种了解,我无法确定地进行调用,而且我可能会使事情变得更糟(对于散列质量很少甚至负增益的算法较慢).
您拥有的一个优点是,由于它本身就是一个ID,因此可能没有其他不相等的对象具有相同的ID,因此不需要检查其他属性.这并不总是成立.
Jon*_*ght 11
您无法从无限长度的字符串中获取唯一的整数.有4亿个(2 ^ 32)个唯一整数,但几乎是无限数量的唯一字符串.
String.hashCode()
不会给你唯一的整数,但它会尽力根据输入字符串给你不同的结果.
编辑
您编辑的问题表明不建议使用String.hashCode().这是不正确的,建议,除非您有一些特殊原因不使用它.如果您有特殊原因,请提供详细信息.
看起来您那里有一个以36为底的数字(az + 0-9)。为什么不使用将其转换为int Integer.parseInt(s, 36)
?显然,如果唯一ID太多,则不能将其放入int
,但在这种情况下,您就不能使用唯一整数了,因此需要使用String.hashCode()
,它会尽最大可能接近唯一。