我有一个对象,其中包含一个字符串,用于保存唯一的ID(例如“ocx7gf”或“67hfs8”)。 我需要提供一个实现int hascode()方法的对象,使其具有唯一性。
最简单/最快的方法如何将字符串转换为唯一的整数?
谢谢。
编辑-好的,我已经知道String.hashcode是可能的。但在任何地方都不推荐使用它。实际上,如果没有其他建议的方法-当我的对象在集合中并且我需要哈希码时,我应该使用它吗?我应该将其连接到另一个字符串中以使其更加成功吗?
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
的编写者无法掌握这些知识,必须尽量照顾每个人。
因此,假如我知道给定的字符串始终由6个大小写不敏感的字符组成,在[a-z]或[0-9]范围内(您的问题似乎是这样的,但不清楚),那么我可以使用一种算法为每个字符分配从0到35(每个字符的36个可能值)之间的值,然后遍历整个字符串,每次将当前值乘以36并加上下一个字符的值。
假设ID分布良好,这将是最佳选择,特别是如果我使得哈希中低位数的数字与ID中最频繁更改的字符匹配(如果可以这么说),因此在重新哈希为较小范围时仍能保持良好的表现。
不过,缺乏对格式的确切了解,我不能确定做出这样的决策,并且我可能会使情况变得更糟(使用更慢的算法而实际上哈希质量并没有提高或甚至降低)。
您有一个优势,即由于它本身是一个ID,则假定没有其他非相等对象具有相同的ID,因此无需检查其他属性。但并非总是如此。
无法从长度不受限制的字符串中获取唯一的整数。有大约40亿(2^32)个唯一的整数,但是有无限多个唯一的字符串。
String.hashCode()
不能给你唯一的整数,但它会尽力根据输入字符串给出不同的结果。
编辑
您编辑后的问题说String.hashCode()
不推荐使用。这不正确,它是推荐使用的,除非您有特殊原因不使用它。如果确实有特殊原因,请提供详细信息。
看起来你有一个基于36进制的数字(a-z + 0-9)。为什么不使用Integer.parseInt(s, 36)
将其转换为int类型?显然,如果有太多唯一的ID,它将无法适合一个int
,但在这种情况下,你只能使用String.hashCode()
,它尽最大努力接近唯一。
long
可能比 int
更值得考虑。 - Peter LawreyhashCode()
返回的是一个 int
,而不是一个 long
。否则我会建议你使用它。 - Jonathanlong
或者甚至是 BigInteger
。 - Jonathan除非您的字符串在某种程度上受限,或者您的整数比您要转换的字符串包含更多位,否则无法保证唯一性。
假设您有一个32位整数和一个64个字符的字符集用于您的字符串。这意味着每个字符六位。这将允许您将五个字符存储到整数中。超过五个字符就不能存储。
String.hashCode()
。如果您想优化代码,则很有可能您的代码中有许多其他地方可以从优化中受益。 - Frans