2015-03-31 40 views
0

這段代碼是否可以用hashCode作爲一個簡單的增量,以負數開始?將散列碼作爲簡單增量可以嗎?

private volatile static AtomicInteger creations = new AtomicInteger(Integer.MIN_VALUE); 
private final int creation; 

{ 
    creation = creations.getAndIncrement(); 
} 

@Override 
public int hashCode() { 
    return creation; 
} 

@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    if (creation == ((Stuff) obj).creation) 
     return true; 
    else 
     return false; 
} 

哈希碼通常是用素數編碼而不是簡單增量? (之所以我希望它是這樣的,是因爲我用這個類創建的每個對象都是唯一的,我希望能夠稍後將它從HashMap中移除,即使對象的狀態將改變,因爲它是我的理解哈希是否發生變化,然後在添加哈希映射後無法將其從哈希映射中移除)爲了防止這種情況成爲簡單的是或否,請向我解釋執行哈希的優點和缺點。

+0

「哈希碼通常是用素數編碼的,而不是用簡單的增量?首先,我不認爲哈希碼通常是素數;散列**表**通常具有素數作爲大小,但這是完全不同的事情。其次,使用一個簡單的增量在你的情況下工作,因爲你只有一個字段,並且該字段恰好是增量。但這是一個非常不尋常的情況。在大多數現實生活中,使用遞增的值作爲哈希代碼是一個很大的失敗,除非沒有兩個不同的對象是相等的,然後增量是毫無意義的。 – ajb 2015-03-31 06:52:09

+0

@ajb我之所以不希望兩個對象具有相同的散列,以及爲什麼我希望以這種方式計算散列,是因爲在HashMap中,如果哈希已更改,我無法刪除它。所以基本上,這使得我無法爲基於狀態的哈希創建我的對象,這些對象是不斷變化的狀態。 – CodeCamper 2015-03-31 06:55:55

+0

好的,那就是_your_用例。但是如果你問爲什麼散列碼通常不是使用一個簡單的增量來計算的,那是因爲你的用例不是典型的。而這種方法在元素放入哈希表的典型情況下不起作用。 – ajb 2015-03-31 07:01:26

回答

2

一般來說,這並不好。 object1.equals(object2)返回true的兩個對象必須具有相同的hashCode

但是,在您的特定情況下,如果對象相等的唯一標準是創建屬性,該屬性與hashCode中使用的屬性相同,則您的hashCode沒問題。

然而,你hashCodeequals沒有提供多少好處超過Object的默認實現,因爲a.equals(b)爲真當且僅當a==b

+1

我認爲他們做... – assylias 2015-03-31 06:44:55

+0

@assylias我只是在發佈我的答案後纔讀取OP的equals方法。現在編輯答案。 – Eran 2015-03-31 06:47:09

+0

我覺得標題很混亂。如果你只讀了標題,答案通常是「否」。 – ajb 2015-03-31 06:48:40

2

是的沒關係(如果兩個實例是相等的,它們具有相同的哈希碼),儘管您的equals/hashcode實現與Object的默認實現沒有太大關係,所以沒有必要這麼做 - 除非您希望對象等於每2^32個實例創建。

根據你的補充,我將與帕特里夏沙納漢的建議,同意使用identityHashCode

@Override 
public int hashCode() { 
    return System.identityHashCode(this); 
} 

@Override 
public boolean equals(Object obj) { 
return this == obj; 
} 

這本質上是在默認情況下所做的對象。就碰撞而言,我懷疑你會比你的碰撞有更多的碰撞。

+0

由於某種原因,我沒有想到這個......所以它真的會產生與默認實現相同的結果?目前,我正在和班上一起壓倒課程。有沒有一種方法可以恢復默認實現,或者是我實現它的方式,幾乎是實現這一目標的最佳方式? – CodeCamper 2015-03-31 06:46:27

+1

@CodeCamper只需刪除這兩個方法,你就會繼承Object的默認實現。 – assylias 2015-03-31 06:47:10

+0

對於這個特殊的例子,我擴展了一個不是我的代碼的類。我是否應該將源代碼複製並粘貼到我自己的類中,並刪除這兩個方法,因爲現在擴展該類保持對我來說很好和乾淨,我想無法以這種方式從子類中刪除方法。另外,如何避免對象每2^32實例創建都相等,因爲不是HashCode限制爲Integer?起初,我希望HashCode能夠很長時間,直到我意識到這是設計中的整數。 – CodeCamper 2015-03-31 06:49:24

相關問題