首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java-当字符串很大时,hashCode()函数如何输出小(或负)数字

Java-当字符串很大时,hashCode()函数如何输出小(或负)数字
EN

Stack Overflow用户
提问于 2015-03-10 10:16:26
回答 3查看 604关注 0票数 1

我做了这个函数,当你输入一些短的东西时,它和原始的Java函数一样工作,但是如果我输入一些大于5-7个字符的东西,那么我就得到了一些真实的大数字。(而不是正确的哈希码)

以下是Java的散列函数的公式:

代码语言:javascript
运行
复制
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

简单一点(只适用于短字符串):

代码语言:javascript
运行
复制
s = "abc" //String
n = 3 //Lenght of the String
s[0] = 'a'. ASCII code of 'a' = 97.
97 * (31 ^ (n - 1))
97 * (31 ^ (2))
97 * 961 = 93217

s[1] = 'b'. ASCII code of 'b' = 98.
98 * (31 ^ (n - 2))
98 * (31 ^ 1)
98 * 31 = 3038

s[2] = 'c'. ASCII code of 'c' = 99.
99 * (31 ^ (n - 3))
99 * (31 ^ 0)
99 * 1 = 99

93217 + 3038 + 99 = 96354 //

我想知道即使当我输入一个巨大的字符串时,Java如何使散列变得很小。

代码语言:javascript
运行
复制
Java's hashcode of "Hello" - 69609650
My hashcode of "Hello" - 69609650


Java's hashcode of "Welcome to Tutorialspoint.com" - 1186874997
My hashcode of "Welcome to Tutorialspoint.com" - 5.17809991536626e+43

另外,如果我们把数字加起来,哈希怎么会是负数呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-03-10 10:20:50

字符串的hashCode只涉及int加法和乘法,因此它会导致int溢出(因此产生负值)。

代码语言:javascript
运行
复制
public int hashCode() {
    int h = hash;
    int len = count;
    if (h == 0 && len > 0) {
        int off = offset;
        char val[] = value;
        for (int i = 0; i < len; i++) {
            h = 31*h + val[off++];
        }
        hash = h;
    }
    return h;
}

根据您的5.17809991536626e+43值,看起来您正在进行浮点计算(也许您使用的是返回doubleMath.pow() ),这给出了不同的结果。

票数 2
EN

Stack Overflow用户

发布于 2015-03-10 10:19:22

我怀疑您的实现(您还没有展示)使用BigInteger或类似的东西。Java只是使用int --所以当它溢出正31位整数的范围时,它会进入大的负整数,然后当你添加更多的(正)值时,你会得到小的负整数,然后是小的正整数,然后是大的正整数--然后返回到大的负数。

票数 3
EN

Stack Overflow用户

发布于 2015-03-10 10:24:05

String$hashCode()的源代码

代码语言:javascript
运行
复制
 1494       public int hashCode() {
 1495           int h = hash;
 1496           if (h == 0 && count > 0) {
 1497               int off = offset;
 1498               char val[] = value;
 1499               int len = count;
 1500   
 1501               for (int i = 0; i < len; i++) {
 1502                   h = 31*h + val[off++];
 1503               }
 1504               hash = h;
 1505           }
 1506           return h;
 1507       }

int是4个字节上的有符号整数,在哈希计算过程中它只会溢出,得到的值可以是负值,但总是受int约束。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28961023

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档