Java—当字符串较大时,hashCode()函数如何输出较小(或负值)的数字

Java—当字符串较大时,hashCode()函数如何输出较小(或负值)的数字,java,string,hash,Java,String,Hash,我做了这个函数,当你输入一些短的字符时,它的工作原理和原来的Java函数一样,但是如果我输入的字符大于5-7个,那么我会得到一个真正的大数字。而不是正确的哈希代码 下面是Java哈希函数的公式: s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] Simpler one仅适用于短字符串: s = "abc" //String n = 3 //Lenght of the String s[0] = 'a'. ASCII code of 'a' = 97. 9

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

下面是Java哈希函数的公式:

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
Simpler one仅适用于短字符串:

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是如何使散列变小的,即使我输入了一个巨大的字符串

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

如果我们把数字加起来,散列怎么可能是负数呢?

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

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

字符串的哈希代码只涉及整数的加法和乘法,因此它会导致整数溢出,从而产生负值

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值,看起来您正在进行浮点计算。可能您使用的是Math.pow,它返回一个double,这会对大数给出不同的结果。

字符串的哈希代码只涉及int加法和乘法,因此它会导致int,从而可能溢出负值

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值,看起来您正在进行浮点计算。可能您使用的是Math.pow,它返回一个double,这会对大数给出不同的结果。

字符串$hashCode的源代码:

int是一个4字节的有符号整数,在散列计算期间它将溢出,产生一个可以为负数但始终受int约束的值。

字符串$hashCode的源代码:

int是一个4字节的有符号整数,在散列计算期间它将溢出,产生一个可以为负数但始终受int约束的值