Object-hashCode演算法筆記
hashCode()是什麼
Object的hashCode()通過JVM虛擬機器來實現其演算法,主要為物件計算出一個hash值
hashCode()的作用及怎麼用:
通過該hash值可以高效的對兩個物件進行比較,比較邏輯如下:
if (A.hash != B.hash){
A != B
}else {
if (A.equals != B.equals) {
A != B
} else {
A == B
}
}
輔助理解:
Object的hashCode演算法會被很多基礎類使用,比如HashMap中計算hash值,但在跟蹤jdk 1.8原始碼時發現hashCode定義是native,所有就需要去扣hashCode原始碼(Object中hashCode的宣告:public native int hashCode();)
在扣原始碼之前有些朋友誤以為預設情況下,hashCode返回的就是物件的儲存地址,事實上這種看法是不全面的,確實有些JVM在實現時是直接返回物件的儲存地址,但是大多時候並不是這樣,只能說可能儲存地址有一定關聯。下面是HotSpot JVM中生成hash雜湊值的實現:
static inline intptr_t get_next_hash(Thread * Self, oop obj) {
intptr_t value = 0 ;
if (hashCode == 0) {
// This form uses an unguarded global Park-Miller RNG,
// so it's possible for two threads to race and generate the same RNG.
// On MP system we'll have lots of RW access to a global, so the
// mechanism induces lots of coherency traffic.
value = os::random() ;
} else
if (hashCode == 1) {
// This variation has the property of being stable (idempotent)
// between STW operations. This can be useful in some of the 1-0
// synchronization schemes.
intptr_t addrBits = intptr_t(obj) >> 3 ;
value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ;
} else
if (hashCode == 2) {
value = 1 ; // for sensitivity testing
} else
if (hashCode == 3) {
value = ++GVars.hcSequence ;
} else
if (hashCode == 4) {
value = intptr_t(obj) ;
} else {
// Marsaglia's xor-shift scheme with thread-specific state
// This is probably the best overall implementation -- we'll
// likely make this the default in future releases.
unsigned t = Self->_hashStateX ;
t ^= (t << 11) ;
Self->_hashStateX = Self->_hashStateY ;
Self->_hashStateY = Self->_hashStateZ ;
Self->_hashStateZ = Self->_hashStateW ;
unsigned v = Self->_hashStateW ;
v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ;
Self->_hashStateW = v ;
value = v ;
}
value &= markOopDesc::hash_mask;
if (value == 0) value = 0xBAD ;
assert (value != markOopDesc::no_hash, "invariant") ;
TEVENT (hashCode: GENERATE) ;
return value;
}
該實現位於hotspot/src/share/vm/runtime/synchronizer.cpp檔案下。如上參考:淺談Java中的hashcode方法
在有些情況下,程式設計者在設計一個類的時候為需要重寫equals方法,比如String類,但是千萬要注意,在重寫equals方法的同時,必須重寫hashCode方法。為什麼這麼說呢?
主要是Object原生的hash值可以理解為取的是物件地址,如果比較兩個String的話,兩個物件的地址一定不同,如果不重寫hashCode兩個物件一定不相同(相同的意思是內容相同,而不是同一個物件),故為了達到時兩個物件內容相同的情況下hashCode相關,則需重寫Object.hashCode();且保證只要後設資料相同,則hashCode必須相同,不相同的後設資料hashCode也可以相同
hash主要提供了一種快速查詢的手段,但該手段同時會引入衝突問題,如何解決衝突問題的方法則將在後續闡述
相關文章
- 【筆記】辛普森演算法筆記演算法
- 演算法筆記整理演算法筆記
- 《演算法圖解》筆記演算法圖解筆記
- 演算法學習筆記演算法筆記
- 演算法學習筆記:Kosaraju演算法演算法筆記
- Tarjan 演算法學習筆記演算法筆記
- 演算法·理論:Manacher 筆記演算法筆記
- 演算法·理論:KMP 筆記演算法KMP筆記
- Floyd演算法學習筆記演算法筆記
- k-means演算法筆記演算法筆記
- LMF演算法學習筆記演算法筆記
- swift演算法練習筆記Swift演算法筆記
- 演算法筆記習題3.5演算法筆記
- 演算法筆記習題3.4演算法筆記
- 演算法筆記習題3.3演算法筆記
- 匈牙利演算法學習筆記演算法筆記
- 演算法學習筆記(3.1): ST演算法演算法筆記
- 【演算法】演算法圖解筆記_快速排序演算法圖解筆記排序
- 圖論最短路演算法筆記圖論演算法筆記
- 莫隊演算法學習筆記演算法筆記
- 演算法筆記 - 樹的直徑演算法筆記
- 漫畫演算法筆記 最小棧演算法筆記
- Virtual Dom演算法實現筆記演算法筆記
- 強化學習演算法筆記之【DDPG演算法】強化學習演算法筆記
- [演算法學習筆記] 並查集演算法筆記並查集
- 演算法學習筆記:2-SAT演算法筆記
- Javascript常見排序演算法的筆記JavaScript排序演算法筆記
- 機器學習筆記(KNN演算法)機器學習筆記KNN演算法
- 【演算法學習筆記】篩法(演算法翻譯類)演算法筆記
- cmu15545筆記-Join演算法(Join Algorithms)筆記演算法Go
- 演算法筆記——馬拉核彈(Mana Nuclear)演算法筆記
- 強化學習筆記之【SAC演算法】強化學習筆記演算法
- [演算法學習筆記] 差分約束演算法筆記
- 機器學習演算法學習筆記機器學習演算法筆記
- 演算法學習筆記(16):Link Cut Tree演算法筆記
- 演算法學習筆記(23):杜教篩演算法筆記
- 【演算法學習筆記】概率與期望DP演算法筆記
- 演算法筆記(廣度優先搜尋)演算法筆記