1 如果兩個對象相同,那么它們的hashCode值一定要相同。也告訴我們重寫equals方法,一定要重寫
hashCode方法,同一個對象那么hashcode就是同一個(同一個對象什么都是相同的)。
2 如果兩個對象的hashCode相同,它們並不一定相同,這里的對象相同指的是用eqauls方法比較。
Object類中hashCode()方法的聲明如下:
Object類中hashCode()方法的聲明如下:
1 public native int hashCode();
可以看出,hashCode()是一個native方法,而且返回值類型是整形;實際上,該native方法將對象在內存中的地址作為哈希碼返回,可以保證不同對象的返回值不同。
2、hashCode()的作用
總的來說,hashCode()在哈希表中起作用,如HashSet、HashMap等。
當我們向哈希表(如HashSet、HashMap等)中添加對象object時,首先調用hashCode()方法計算object的哈希碼,通過哈希碼可以直接定位object在哈希表中的位置(一般是哈希碼對哈希表大小取余)。如果該位置沒有對象,可以直接將object插入該位置;如果該位置有對象(可能有多個,通過鏈表實現),則調用equals()方法比較這些對象與object是否相等,如果相等,則不需要保存object;如果不相等,則將該對象加入到鏈表中。
這也就解釋了為什么equals()相等,則hashCode()必須相等。如果兩個對象equals()相等,則它們在哈希表(如HashSet、HashMap等)中只應該出現一次;如果hashCode()不相等,那么它們會被散列到哈希表的不同位置,哈希表中出現了不止一次。
實際上,在JVM中,加載的對象在內存中包括三部分:對象頭、實例數據、填充。其中,對象頭包括指向對象所屬類型的指針和MarkWord,而MarkWord中除了包含對象的GC分代年齡信息、加鎖狀態信息外,還包括了對象的hashcode;對象實例數據是對象真正存儲的有效信息;填充部分僅起到占位符的作用, 原因是HotSpot要求對象起始地址必須是8字節的整數倍。
hashcode:返回值是int值,並且每次運行的結果不一樣,可以理解為內存編號,便於CPU 快速查找。當
然自己可以去重寫hashcode方法,但是要保證每個對象的hashcode值不一樣,如果一樣,那么CPU查找這
個對象的時候就會出錯。
一致性hash 算法
int型占4個字節,有32位,所以有2^31-1個,即2147483647。因為我們這里用的是int值來標識位置信息,所以環的長度是Interger的最大值。否則會覆蓋。
原來ACB3個機器,現在增加D這個機器。緩存失效也只有部分緩存失效。失效的緩存將會在后端真實服務器去取。
hash傾斜:會導致ABC3台機器在環上分配不均勻,那么所有的數據都在機器A上,當緩存失效的時候會有大量數據失效,從而加重后端非緩存機器的崩潰,所以可以在環上加很多虛禮節點,A加點虛擬出A1 A2 A3 ...,數據讀寫的時候,先算出虛禮節點的位置,然后找到真實節點,在把數據放入真實節點進行讀寫。虛禮節點也會跟真實節點碰撞。