[英]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.