将从字符串派生的唯一编号转换为良好的哈希码

时间:2013-12-09 05:34:18

标签: java string hashcode

我有一个应用程序需要非常快速地比较很多小字符串。幸运的是,我可以保证关于所有字符串的以下内容:

  • 每个字符串中只有前6个字符被认为是重要的;
  • 将忽略任何剩余字符的差异
  • 比较不区分大小写
  • 字符串中只允许(英文)字母,“ - ”和“'”。

我突然意识到,有可能将每个字符串转换为int,可以直接与其他字符串生成的int进行比较,从而转换成本很高的字符串字符串比较为单周期整数比较。

但是,我还需要将这些字符串用作哈希表中的键(特别是Java的HashMapHashSet类),并且想知道我生成的数字是否可以用作良好的哈希码,或者很容易转换成它们,或者如果我还应该使用更传统的字符串哈希算法为我的对象生成哈希码。我自己可以进行一次性能测试,但是我发现这个确切的问题是某人之前很可能已经评估过的事情。我只是在努力寻找有关它的任何好消息。

我的唯一编号生成代码如下:

private int stringMatcherCode (String word)
{
    int total = 0;
    for (int i = 0; i < word.length() && i < 6; i ++)
    {
        char ch = word.charAt (i);
        if (ch == '-') ch = (char)28;  // does not contain the same last 5 bits as any letter
        if (ch == '\'') ch = (char)29; // nor this
        total = (total << 5) | (ch & 0x1F);
    }
    return total;
}

1 个答案:

答案 0 :(得分:-1)

当我提出这个问题时,我没有的关键见解是Java的HashMap实现使用了两个幂大小的表(我以为它的工作方式与我多年前学过的方式一样,你保持了大小表到素数)。鉴于我的实现,因此在选择任何给定字符串映射到的存储桶时,只有较早的字符才有意义。因此素数是乘法器的更好选择 - 31对我来说并不好,但是,因为我可以很容易地保证它的独特性,因为我可以使用它.33然而,33确实有效,因为33 ^ 6仍然是&lt ; 2 ^ 32,所以不会发生溢出,所以这个实现都保证唯一性可以作为一个好的哈希码:

private int stringMatcherCode (String word)
{
    int total = 0;
    for (int i = 0; i < word.length() && i < 6; i ++)
    {
        char ch = word.charAt (i);
        if (ch == '-') ch = (char)28;  // does not contain the same last 5 bits as any letter
        if (ch == '\'') ch = (char)29; // nor this
        total = (total * 33) + (ch & 0x1F);
    }
    return total;
}