2013-07-17 105 views
-1

我使用eclipse生成覆蓋Object的hashCode和equals方法,並生成了一些關於hashCode覆蓋的問題。下面的hashCode()是否正確?Eclipse自動生成的hashCode覆蓋

問題:

- 爲什麼不蝕產生兩個結果=行代碼?我認爲將這兩個結果加在一起是適當的。任何想法爲什麼他們是單獨的任務?

- 最終的int prime可以是任何素數嗎?

-Should int result always be 1?

public class Overrider { 
    private Long id; 
    private String name; 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((id == null) ? 0 : id.hashCode()); 
     result = prime * result + ((name == null) ? 0 : name.hashCode()); 
     return result; 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Overrider other = (Overrider) obj; 
     if (id == null) { 
      if (other.id != null) 
       return false; 
     } else if (!id.equals(other.id)) 
      return false; 
     if (name == null) { 
      if (other.name != null) 
       return false; 
     } else if (!name.equals(other.name)) 
      return false; 
     return true; 
    } 
} 
+0

的[可能重複重寫equals和hashCode在Java](http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java) –

+0

它不是一個重複的,我想知道,如果Eclipse插入是有效的,因爲它不同於其他我見過的例子 – c12

+0

「_任何想法爲什麼他們是單獨的任務?」因爲可讀代碼比干擾大量邏輯成一行的垃圾好得多。 – jahroy

回答

1

對我來說很好。

「爲什麼eclipse會生成兩個結果=代碼行?」

我猜的原因是可讀性。它看起來像是將第一個結果+第二個字段的散列值再乘以總數,而不僅僅是將兩條線相加。生成的代碼看起來比好多了:「能否最終詮釋主要是任意素數」

result = (prime * result + ((id == null) ? 0 : id.hashCode())) + 
     (prime * (prime * result + ((id == null) ? 0 : id.hashCode())) + 
     ((name == null) ? 0 : name.hashCode())); 

是的,但越高越好。數字越高,減少碰撞的可能性越大。在大多數情況下,31應該綽綽有餘。

「應該int結果總是1?」

假設你的意思是「應該詮釋的結果總是被初始化到1」:

不,它只是需要一些常量,它不是0

+0

結果最初爲1,因此您可以取消它。 –

1

- 爲什麼不蝕產生兩個結果=行代碼?我認爲將這兩個結果加在一起是適當的。任何想法爲什麼 他們是單獨的任務?

請記住,這是在eclipse中運行以生成代碼的代碼。因此,有一個特定的邏輯。 爲每個變量生成一行而不是對所有行生成一行更容易。

此外,它使代碼更具可讀性......你能想象將這兩個語句合併爲一個嗎?

return prime * (prime + ((id == null) ? 0 : id.hashCode())) + 
((name == null) ? 0 : name.hashCode()); 

我不會簡化打擾,但如果有10類變量會變得相當大,可怕的......

「能否最終詮釋主要是任意素數?」

看一看:Why does Java's hashCode() in String use 31 as a multiplier? 我從那裏報價,其中報價書「有效的Java」 ......

據約書亞Bloch的Effective Java的(一本書,不能 建議不夠,我要不斷提到上 計算器)由於買:

「的值31的選擇是因爲它是一個奇素數如果是連 和乘法溢出,信息會因爲 乘以2相當於移位。使用 素數的優點不太清楚,但它是傳統的。 31的一個不錯的屬性是 ,乘法可以被移位和減法 代替以獲得更好的性能:31 * i ==(i < < 5) - i。現代的虛擬機自動執行此 排序的優化。」

1

- 爲什麼不偏食產生兩個結果=行代碼?我認爲,增加這兩個結果放在一起是合適的。任何想法,爲什麼他們是獨立的任務? 答案:你已經確定了'final int prime = 31;'之上定義的素數。 假設下列情況

id.hashcode()= 1 & name.hashcode()= 2。 Hashcode方法通過加入= 32 + 33 = 65 Hashcode方法與實施蝕=

id.hashcode()= 2 & name.hashcode()= 1。 Hashcode方法通過加入= 33 + 32 = 65 Hashcode方法與實施蝕=

Hashcode方法應該是儘可能唯一獲得更好的性能。如果添加結果,可能會有2個不同的對象返回相同的散列碼。而在乘法的情況下,對於不同的對象有重複的哈希碼的機會很少。

- 最終的int prime可以是任何素數嗎? 它可以是任何數字,但它可以確保對於不同的對象將有很少可能的重複哈希碼。上面的表格31表示,即使2個不同對象的id.hash代碼中的1的差值將確保這兩個對象的實際的哈希碼將至少相差31個。S

- 如果int結果總是1? 它可以是任何東西。這只是它應該是非零的,並且應該避免計算的複雜性以使其工作得更快。