DIY主題討論20:哈希碼的計算
1)自主選擇一個類,說明它hashCode方法的設計理念和代碼核心邏輯。
2) 舉例說明。
HashCode
hashCode意義
在編寫類的時候,如果覆蓋了Object的equals方法,那麼必須要覆蓋hashCode方法,並且如果兩個對象用equals方法比較返回true,那麼這兩個對象hashCode返回的值也必須是相等的,並且對於同一個對象,equals方法需要比較的屬性值沒有被修改,那麼每次調用hashCode返回的值應該是一致的。
hashCode的主要目的就是爲了提高諸如java.util.HashMap這樣的散列表(hash table)的性能,散列表(hash table)需要保證集合的不重複,每個新加入的元素都要跟已經存在的元素不相等,一個個equals顯然性能很差,所以引入hashCode。
hashCode方法的設計理念
- 重寫equals()而重寫hashCode(),重寫hashCode()而重寫equals()
- 將hashCode分爲兩種:單個類的hashCode和容器類(集合數組)的hashCode
- hashCode設計核心公式:s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1],乘法因子是31
- hash算法乘法因子需要時素數,且越大越好
- 乘法因子是31原因:計算機計算31比較快,31 * i = (i << 5) - i ,另一原因對超過5W個英文單詞做測試,在取31情況下,碰撞的次數都不超過7次
- hash算法設計理念核心是降低衝突率,不同對象的hashCode儘量不要相等
hashCode代碼核心邏輯(舉例——Arrays)
爲什麼重寫HashCode?
在Arrays重寫了long、int、short、char、byte、boolean、float、double、Object,8個基本類型和Object類型的hashCode,在這個類中我想是因爲可以提供每種類型的equals()比較方法而重寫hashCode,如果不重寫equals(),那麼Arrays是個數組對象,Object對象使用內存地址來作爲hashCode,兩個相同值的Arrays對象會應爲內存地址不同而不相等,因此需要重寫equals()方法,進而需要重寫hashCode方法。
HashCode方法邏輯
- 空Arrays的hashCode爲0,只有一個對象,且對象爲null的hashCode爲0
- 非空Arrays遍歷每個元素得到hashCode
- Arrays得出的hashCode與List得出的hashCode是一樣的
- Arrays.hashCode()會計算一維數組元素的hashCode,如果是多維數組,那麼需要遞歸進行hashCode的計算,使用Arrays.deepHashCode(Object[])方法。
- 循環內部基本計算公式 result = 31 * result + elementHash;
計算邏輯
- 如果是long值,則elementHash = (int)(f ^ (f >>> 32))
- 如果是int值,則elementHash = int值
- 如果是short值,則elementHash = short值
- 如果是char值,則elementHash = char值
- 如果是byte值,則elementHash = byte值
- 如果是boolean值,則elementHash = element ? 1231 : 1237,附註boolean的hashCode使用1231和1237
- 如果是float值,則elementHash = Float.floatToIntBits(f)
- 如果是double值,則elementHash = (int)(Double.doubleToLongBits(f) ^ (Double.doubleToLongBits(f) >>> 32));
- 如果是Object值,則elementHash = element.hashCode()
long與double都使用了f ^ (f >>> 32)),因爲long與double都是64位,需要轉換爲一個int數字——32位
思考
在jdk源碼中,都有哪些類重寫類hashCode,爲什麼?
equals方法的設計理念和代碼核心邏輯?
參考
https://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier
https://m.imooc.com/article/22958
https://blog.csdn.net/qq_21251983/article/details/52164403