Java中hashCode的實現
從我們剛學Java就知道,要重寫equal就要一起重寫hashCode.但是你有了解過hashCode的實現嗎?
什么是hashCode
hash是把任意長度的輸入(又叫做預映射pre-image)通過散列算法變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間通常遠小于輸入的空間,不同的輸入可能會散列成相同的輸出,所以不可能從散列值來確定唯一的輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。<摘自百度百科>
總結
- 能夠將數據壓縮
- 針對同一輸入具有唯一輸出
- 存在數據沖突
hashcode能干什么
根據以上特性,很顯然我們可以用hash比較2個對象是否相等。這也是為什么Java重新equal就要重寫hashCode的原因。
Java的實現
既然Java中所以的對象都繼承自Object。那我們就看看Object的hashCode實現吧。
hashcode.png
竟然是native方法,查看hash實現源碼發現有以下實現方式。
- 隨機數
- 基于內存地址生成
- 固定值:1,用來測試
- 自增
- 利用位移生成隨機數
可以看到除了第三種,其余的算法都不具有一致性。那么當我們沒有重新Object.hashCode()的時候,JVM是怎么處理生成的hashcode呢?
對象頭
jvm 將這種方式生成的hashcode存到了Java對象頭 里。
對象頭只是存儲Object.hashCode()方法生成的hash。如果我們重新的hashCode()方法便不需要存到對象頭。