Java中的哈希值

一、Hash值有什麼用?數組

     HashMap、HashTable、HashSet,因此涉及到使用Hash值進行優化存儲的地方,都會用到HashCode。HashCode是Key,這種計算爲提升計算的性能。想一想看,通常來講,數組算是比較快的集合類了吧,直接用index定位元素,簡直就是O(1)的級別。可是添加元素就不這麼樂觀了。可是使用hash類的集合,添加元素,移動的元素少,隻影響一小塊,而且查找元素,因爲hash值已經進行了定位分組,因此也會大大縮小涉及面,快速定位。性能

 

二、Hash值應該符合什麼原則?優化

     A、等冪性。無論執行多少次獲取Hash值的操做,只要對象不變,那麼Hash值是固定的。若是第一次取跟第N次取不同,那就用起來很麻煩,須要記錄當前是第幾回操做,這種須要記錄狀態的事情,可不是什麼好事。code

     B、對等性。若兩個對象equal方法返回爲true,則其hash值也應該是同樣的。舉例說明:若你將objA做爲key存入HashMap中,而後new了一個objB。在你看來objB和objA是一個東西(由於他們equal),可是使用objB到hashMap中卻取不出來東西。對象

     C、互異性。若兩個對象equal方法返回爲false,則其hash值最好也是不一樣的,但這個不是必須的,只是這樣作會提升hash類操做的性能(碰撞概率低)。hash

 

三、Hash值應該怎麼計算?方法

   A、簡單計算就是組成成員的hash值直接相加便可。好比ObjectA有三個屬性,propA、propB和propC,最直接的計算方式就是propA.hashcode+propB.hashcode+propC.hashcode。集合

 

   B、可是若是遇到有順序相關的怎麼辦?好比String類型是由char數組組成,而且這些數組是有順序的。若是使用第一種計算方法,則「ABCD」和「BCDA」就會產生一樣的hashCode,那麼怎麼辦呢?最直接想到的辦法就是加權,不一樣的index加不一樣的權值,這個權值的肯定最直接的方法就是某個常數值的幾回冪。好比爲String的計算hash值爲K^0*A.hashCode+K^1*B.hashCode+K^2*C.hashCode+K^3*D.hashCode。K的選擇也有說法,最好不要是偶數,由於偶數的相乘會形成信息的丟失(乘以2就是左移1位,一旦溢出就會形成信息的丟失,這種計算會形成溢出後的值與某個看似不相關的數值獲得的結果是同樣的),因此最好是奇數,在這一點上比較推薦使用7,由於7=8-1=2^3-1,這樣計算的時候,直接左移幾位再進行一次普通的加減法便可(Java中經常使用的是31(32-1=2^5-1))。移動

相關文章
相關標籤/搜索