簡體   English   中英

Java-當字符串較大時,hashCode()函數如何輸出較小(或負數)的數字

[英]Java - How can hashCode() function output small (or negative) number when string is big

我做了這個函數,當您輸入簡短的內容時,它的功能與原始Java函數相同,但是如果我輸入的內容大於5-7個字符-那么我會得到一些真正的大數字。 (而不是正確的哈希碼)

這是Java哈希函數的公式:

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

簡化器一(僅適用於短字符串):

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位正整數的范圍時,它會變成大的負整數,然后當您添加更多(正)值時,最終會得到小的負整數,然后是小的正整數,然后是大的正整數-然后返回大的負整數。

字符串的hashCode僅涉及int加法和乘法,因此它導致一個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 ),這將為大數提供不同的結果。

String$hashCode()源代碼:

 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約束。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM