2014-11-03 42 views
0

不同的對象相同數量比方說,我有這種情況長的hashCode返回在Java

Long id = -1L; 
    System.out.println(id.hashCode()); 

    id = 0L; 
    System.out.println(id.hashCode()); 

你猜怎麼着?兩個輸出都給出相同的數字(0)!我的問題是:

  1. 爲什麼會發生這種情況?
  2. 我怎樣才能省略這個並計算適當的散列0和-1?

預先感謝答覆:)

+2

你似乎認爲散列總是唯一的。他們不是。有2^64個長,2^32個可用的哈希碼......顯然會有碰撞。你絕不應該假定具有相同散列碼的兩個值是相等的。他們只是*可能*是平等的。 – 2014-11-03 11:35:50

+0

那麼,我知道可能會發生一些碰撞,但我認爲這將發生在大數目而不是最近的數字。 – 2014-11-03 11:39:14

+0

顯然這是一個危險的假設...如果你編寫你的代碼不要假設它可以把散列碼當作平等的終極仲裁者,那麼它就沒有關係。 – 2014-11-03 11:42:43

回答

5

這究竟是爲什麼?

由於Long.hashCode實現是as follows

結果是獨家通過此Long對象持有的原始長值的兩個部分的異或。也就是說,哈希碼就是表達式的值:

(int)(this.longValue()^(this.longValue()>>>32)) 

我怎麼能忽略這一點,並計算適當的哈希值0和-1?

這些適當的哈希值。哈希不保證是唯一的;實際上,如果存在超過2個可能的輸入值,則保證而不是是唯一的。

如果你想要一個不同的行爲,你需要寫一個MyInteger類,行爲不同(儘管我懷疑沒有真正的理由這樣做)。

0

根據散列函數,2個不同的對象可以有相同的散列碼。

Javadoc

hashCode的一般合同是:

每當它是一個Java應用程序的執行期間,在同一對象不止一次上調用,hashCode方法必須始終 返回相同的整數,沒有提供信息用於等於 對對象進行比較修改。該整數不必保持 從應用程序的一次執行到同一應用程序的另一次執行 的一致。 如果兩個對象根據equals(Object)方法相等,則對兩個對象中的每個對象調用hashCode方法必須產生相同的整數結果。 根據equals(java.lang.Object)方法,如果兩個對象不相等,則不要求在兩個對象的每一個上調用hashCode方法 必須生成不同的整數結果。但是,程序員應該知道,爲不相等的對象生成不同的 整數結果可能會提高散列表的性能。

儘可能合理實用,由 類Object定義的hashCode方法確實爲不同的對象返回不同的整數。 (這 通常是通過轉換 對象的內部地址轉換成一個整數來實現的,但是這種實現技術不是由的JavaTM編程語言不需要 。)