有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何从唯一的字符串生成唯一的int?

我有一个带有字符串的对象,该字符串具有唯一的id。 (如“ocx7gf”或“67hfs8”) 我需要为它提供一个int hascode()的实现,它显然是唯一的

如何以最简单/最快的方式将字符串转换为唯一的int

10倍

编辑-确定。我已经知道那根弦了。哈希代码是可能的。但在任何地方都不建议这样做。实际上,“如果不推荐任何其他方法-如果我在集合中有我的对象并且我需要hashcode,我是否应该使用它?”。我是否应该将其连接到另一个字符串以使其更成功


共 (6) 个答案

  1. # 1 楼答案

    用五位二进制数字表示每个字符串字符,例如a乘00001 b乘00010等。因此,可以使用32种组合,例如,cat可能被写入00100 00001 01100,然后将该二进制转换为十进制,例如,这将是4140,因此cat将是4140,类似地,您可以通过首先将cat转换为二进制并将五位二进制映射为字符串,从4140获取cat

  2. # 2 楼答案

    不,您不需要有一个返回唯一值的实现,“显然”,因为大多数实现都会被破坏

    您要做的是在位之间有一个良好的分布,特别是对于公共值(如果任何值比其他值更公共)。除非您对格式有专门的了解,否则最好只使用字符串本身的哈希代码

    通过对您的id格式限制的专门了解,可以定制并获得更好的性能,尽管错误的假设更可能使事情变得更糟而不是更好

    编辑:在良好的位分布上

    正如本文和其他答案所述,完全唯一是不可能的,哈希冲突也是可能的。使用散列的方法知道这一点并且可以处理它,但是它对性能有影响,所以我们希望冲突很少

    此外,散列通常被重新散列,因此我们的32位数字可能最终被减少到例如0到22范围内的一个,并且我们希望在该范围内尽可能好地分布

    我们还想平衡这一点,不要花太长时间来计算散列,因为散列本身就成了瓶颈。不完美的平衡行为

    坏散列方法的一个经典示例是一个坐标对X,Y int,它执行以下操作:

    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的作者不能研究这些知识,必须设法迎合每个人

    因此,例如,如果我知道一个给定的字符串总是由[a-z]或[0-9]范围内的6个不区分大小写的字符组成(你的答案似乎是这样的,但你的问题并不清楚它是这样的),那么我可能会使用一种算法,为每个字符分配一个0到35之间的值(每个字符36个可能的值),然后遍历字符串,每次将当前值乘以36,然后添加下一个字符的值

    假设在id中有一个良好的排列,这将是一个好办法,特别是如果我进行排序,使哈希中较低的有效数字与id中最频繁变化的字符相匹配(如果可以进行这样的调用),因此可以在较小的范围内进行重新哈希

    然而,由于缺乏这种格式的知识,我无法确定地进行调用,而且我很可能会让事情变得更糟(由于哈希质量几乎没有或甚至是负增益,所以算法速度较慢)

    您拥有的一个优势是,由于它本身是一个ID,因此可能没有其他非相等对象具有相同的ID,因此不需要检查其他属性。这并不总是成立的

  3. # 3 楼答案

    一种方法是给每个字母分配一个值,字符串的每个位置分配它自己的倍数,即a=1,b=2,依此类推,然后第一个数字(从左到右读取)中的所有内容都将乘以一个素数,下一个是下一个素数,依此类推,最后一个数字乘以一个素数,该素数大于该数字中可能的子集数(26+1表示空格,52+1表示大写字母,依此类推,表示其他受支持的字符)。如果数字映射回第一个数字(最左边的字符),则从唯一字符串映射回1或6(无论第一个字母是什么)生成的任何数字都会给出唯一值

    狗可能是30,3(15),101(7)或782,而上帝可能是33,3(15),101(4)或482。与生成的唯一字符串相比,更重要的是,如果保留原始数字,则它们在生成过程中非常有用,例如30(782)对于某些12(782)是唯一的,以便在您尝试过唯一可能性的情况下区分类似字符串。狗永远是狗,但它永远不会是猫或老鼠

  4. # 4 楼答案

    除非字符串以某种方式受到限制,或者整数包含的比特数比要转换的字符串多,否则无法保证唯一性

    假设字符串有一个32位整数和一个64字符集。这意味着每个字符6位。这将允许您将五个字符存储到一个整数中。不止这些,它就不合适了

  5. # 5 楼答案

    看起来你有一个基数为36的数字(a-z+0-9)。为什么不使用Integer.parseInt(s, 36)将其转换为int?显然,如果有太多的唯一ID,它将无法放入int中,但在这种情况下,您不太可能使用唯一整数,需要使用String.hashCode()来获取,这将尽可能接近唯一

  6. # 6 楼答案

    无法从长度不限的字符串中获取唯一整数。有4个十亿(2^32)的唯一整数,但几乎无限多的唯一字符串

    String.hashCode()不会给出唯一的整数,但它会根据输入字符串尽力给出不同的结果

    编辑

    您编辑的问题显示了该字符串。不建议使用hashCode()。这是不正确的,建议你,除非你有特殊的理由不使用它。如果您确实有特殊原因,请提供详细信息