Effective Java Item 9 note

Always override hashCode when you override equals

Arwii
mycodingjourney
3 min readMay 26, 2018

--

如果你有override了equals的話,那麼一定也要override hashCode,如果沒有override hashCode,除了違反Object.hashCode的規定(第二條)之外(因為你沒有保證兩個equals的物件產生一樣的hashCode,sample code放在github上面 https://bit.ly/2IQEfOr),也讓基於hash-base的collection沒辦法使用(HashMap, HashSet, HashTable)

Java的Object規定:

  1. 在application runtime, 只要object的equals所用到的值沒有被修改,那麽多次對同一個object使用,其hashCode必須每次都是同一個整數。
  2. 如果兩個對象透過equals比較是相等的,那麼這兩個對象的hashCode也會是一樣的整數結果
  3. 如果兩個對象透過equals比較是不相等的,那麼這兩個對象的hashCode不一定要是不同的結果,但如果產生不同結果的話是會提高hash table的效能的

那麼hashCode內容要怎麼寫呢?

可以使用IDE應該會有generator幫產生equals跟hashCode。那大原則是盡可能分散各object到hash table中,一個極端的例子是都產生同一個hashCode的話,那麼會讓hash table退化成linked-list,效能就從O(n) -> O(n²)

底下是各種primitive type用android studio auto generate的範例:

切記equals跟hashCode基本上是綁一起的,hashCode當中的計算只會用到有在equals裡面使用的變數,如果使用到equals裡面用到的變數之外的值也是有可能違反上面提到的第二個條件的。

然後書上也有提到,如果一個class是immutable,而且計算hashCode的負擔比較大的話,那們就可以考慮把hashCode存在object裡面,不用每次都算,那如果這個object會被當成是hash key的話,那就可以在constructor的時候就算,不然可以用lazily initialize,等到hashCode被用到的時候再算。

最後不要以為可以提高效能然後企圖移掉任何一個object裡面被拿來算hashCode的值,等到存有大量object的時候就會知道因小失大了。

--

--

Arwii
mycodingjourney

Try not to become a man of success, but rather try to become a man of value — A. Einstein